home *** CD-ROM | disk | FTP | other *** search
/ Enter 2001 April / EnterCD4.iso / Update / SQL Server SP3 / sql70sp3i.exe / INSTALL / replsys.sql < prev    next >
Encoding:
Text File  |  2000-01-10  |  367.4 KB  |  12,450 lines

  1.  
  2. /*
  3. ** replsys.sql            1997/02/12 22:03
  4. **
  5. **
  6. ** Copyright Microsoft, Inc. 1998, 1999
  7. ** All Rights Reserved.
  8. ** Use, duplication, or disclosure by the United States Government
  9. ** is subject to restrictions as set forth in subdivision (c) (1) (ii)
  10. ** of the Rights in Technical Data and Computer Software clause
  11. ** at CFR 252.227-7013. Microsoft, Inc. One Microsoft Way, Redmond WA
  12. ** 98052.  SQL Server 7.0
  13. */
  14.  
  15. dump tran master with no_log
  16. go
  17.  
  18. exec dbo.sp_configure 'update',1
  19. go
  20. reconfigure with override
  21. go
  22.  
  23. set ANSI_NULLS off
  24. go
  25.  
  26. use master
  27. go
  28.  
  29. exec dbo.sp_MS_upd_sysobj_category 1 --Capture time for use at the end
  30. go
  31.  
  32. if exists (select * from sysobjects
  33.     where type = 'P '
  34.             and name = 'sp_MSreplcheck_name')
  35.     drop procedure sp_MSreplcheck_name
  36. go
  37.  
  38. if exists (select * from sysobjects
  39.     where type = 'P '
  40.             and name = 'sp_MSreplcheck_publish')
  41.     drop procedure sp_MSreplcheck_publish
  42. go
  43.  
  44. if exists (select * from sysobjects
  45.     where type = 'P '
  46.             and name = 'sp_MSsetaccesslist')
  47.     drop procedure sp_MSsetaccesslist
  48. go
  49.  
  50. if exists (select * from sysobjects
  51.     where type = 'P '
  52.             and name = 'sp_MScheck_subscription')
  53.     drop procedure sp_MScheck_subscription
  54. go
  55.  
  56. if exists (select * from sysobjects
  57.     where type = 'P '
  58.             and name = 'sp_MSenumcolumns')
  59.     drop procedure sp_MSenumcolumns
  60. go
  61.  
  62. if exists (select * from sysobjects
  63.     where type = 'P '
  64.             and name = 'sp_MSlocktable')
  65.     drop procedure sp_MSlocktable
  66. go
  67.  
  68. if exists (select * from sysobjects
  69.     where type = 'P '
  70.             and name = 'sp_MSreplcheck_connection')
  71.     drop procedure sp_MSreplcheck_connection
  72. go
  73.  
  74. if exists (select * from sysobjects
  75.     where type = 'P '
  76.             and name = 'sp_MSreplcheck_pull')
  77.     drop procedure sp_MSreplcheck_pull
  78. go
  79.  
  80. if exists (select * from sysobjects
  81.     where type = 'P '
  82.             and name = 'sp_MSreplcheck_qv')
  83.     drop procedure sp_MSreplcheck_qv
  84. go
  85.  
  86. if exists (select * from sysobjects
  87.     where type = 'P '
  88.             and name = 'sp_MSpublicationcleanup')
  89.     drop procedure sp_MSpublicationcleanup
  90.  
  91. if exists (select * from sysobjects
  92.     where type = 'P '
  93.             and name = 'sp_MSCleanupForPullReinit')
  94.     drop procedure sp_MSCleanupForPullReinit
  95.  
  96. if exists (select * from sysobjects
  97.     where type = 'P '
  98.             and name = 'sp_MSaddanonymousreplica')
  99.     drop procedure sp_MSaddanonymousreplica
  100.         
  101. if exists (select * from sysobjects
  102.                 where type = 'P' and
  103.                 name = 'sp_reinitmergepullsubscription')
  104.         drop procedure sp_reinitmergepullsubscription
  105.  
  106. if exists (select * from sysobjects
  107.     where type = 'P '
  108.             and name = 'sp_expired_subscription_cleanup')
  109.     drop procedure sp_expired_subscription_cleanup
  110.     
  111.     if exists (select * from sysobjects
  112.     where type = 'P '
  113.             and name = 'sp_MSarticlecleanup')
  114.     drop procedure sp_MSarticlecleanup
  115.  
  116.  
  117.     if exists (select * from sysobjects
  118.     where type = 'P '
  119.             and name = 'sp_MSdroparticleprocs')
  120.     drop procedure sp_MSdroparticleprocs
  121.  
  122.     if exists (select * from sysobjects
  123.     where type = 'P '
  124.             and name = 'sp_MSdroparticletriggers')
  125.     drop procedure sp_MSdroparticletriggers
  126.  
  127.     if exists (select * from sysobjects
  128.     where type = 'P '
  129.             and name = 'sp_MScheckvalidsystables')
  130.     drop procedure sp_MScheckvalidsystables
  131.  
  132. if exists (select * from sysobjects
  133.     where type = 'P '
  134.             and name = 'sp_MSreplcheck_subscribe')
  135.     drop procedure sp_MSreplcheck_subscribe
  136. go
  137.  
  138. if exists (select * from sysobjects
  139.     where type = 'P '
  140.             and name = 'sp_replicationoption')
  141.     drop procedure sp_replicationoption
  142. go
  143.  
  144. if exists (select * from sysobjects
  145.     where type = 'P '
  146.             and name = 'sp_helpreplicationoption')
  147.     drop procedure sp_helpreplicationoption
  148. go
  149.  
  150. if exists (select * from sysobjects
  151.         where type in ('P ') 
  152.             and name = 'sp_MSmergesubscribedb')
  153.     drop procedure sp_MSmergesubscribedb
  154.  
  155. if exists (select * from sysobjects
  156.         where type in ('P ') 
  157.             and name = 'sp_MSremovedbreplication')
  158.     drop procedure sp_MSremovedbreplication
  159.  
  160.  
  161. if exists (select * from sysobjects
  162.     where type = 'P '
  163.             and name = 'sp_addpullsubscription')
  164.     drop procedure sp_addpullsubscription
  165.  
  166. if exists (select * from sysobjects
  167.     where type = 'P '
  168.             and name = 'sp_reinitpullsubscription')
  169.     drop procedure sp_reinitpullsubscription
  170.     
  171. if exists (select * from sysobjects
  172.     where type = 'P '
  173.             and name = 'sp_addmergepullsubscription')
  174.     drop procedure sp_addmergepullsubscription
  175.  
  176. if exists (select * from sysobjects
  177.     where type = 'P '
  178.             and name = 'sp_dropmergepullsubscription')
  179.     drop procedure sp_dropmergepullsubscription
  180.  
  181. if exists (select * from sysobjects
  182.     where type = 'P '
  183.             and name = 'sp_changemergepullsubscription')
  184.     drop procedure sp_changemergepullsubscription
  185.  
  186. if exists (select * from sysobjects
  187.     where type = 'P '
  188.             and name = 'sp_helpmergepullsubscription')
  189.     drop procedure sp_helpmergepullsubscription
  190.  
  191. if exists (select * from sysobjects
  192.     where type = 'P '
  193.             and name = 'sp_MSchange_priority')
  194.     drop procedure sp_MSchange_priority
  195.  
  196. if exists (select * from sysobjects
  197.     where type = 'P '
  198.             and name = 'sp_MSchange_retention')
  199.     drop procedure sp_MSchange_retention
  200.  
  201. if exists (select * from sysobjects
  202.         where type = 'P '
  203.                 and name = 'sp_MSdrop_mergesystables')
  204.         drop procedure sp_MSdrop_mergesystables
  205.  
  206. if exists (select * from sysobjects
  207.         where type = 'P '
  208.                 and name = 'sp_MScreate_mergesystables')
  209.         drop procedure sp_MScreate_mergesystables
  210.     
  211. if exists (select * from sysobjects
  212.     where type = 'P '
  213.             and name = 'sp_addpullsubscription_agent')
  214.     drop procedure sp_addpullsubscription_agent
  215.  
  216. if exists (select * from sysobjects
  217.     where type = 'P '
  218.             and name = 'sp_helpsubscription_properties')
  219.     drop procedure sp_helpsubscription_properties
  220.  
  221. if exists (select * from sysobjects
  222.     where type = 'P '
  223.             and name = 'sp_change_subscription_properties')
  224.     drop procedure sp_change_subscription_properties
  225.  
  226. if exists (select * from sysobjects
  227.     where type = 'P'
  228.             and name = 'sp_MSget_pullsubsagent_owner')
  229.     drop procedure sp_MSget_pullsubsagent_owner
  230.  
  231. if exists (select * from sysobjects
  232.     where type = 'P'
  233.             and name = 'sp_MSget_mergepullsubsagent_owner')
  234.     drop procedure sp_MSget_mergepullsubsagent_owner
  235.     
  236. if exists (select * from sysobjects
  237.     where type = 'P '
  238.             and name = 'sp_addmergepullsubscription_agent')
  239.     drop procedure sp_addmergepullsubscription_agent
  240.  
  241. if exists (select * from sysobjects
  242.     where type = 'P '
  243.             and name = 'sp_droppullsubscription')
  244.     drop procedure sp_droppullsubscription
  245.  
  246. if exists (select * from sysobjects
  247.     where type = 'P '
  248.             and name = 'sp_vupgrade_publisherdb')
  249.     drop procedure sp_vupgrade_publisherdb
  250.  
  251. if exists (select * from sysobjects
  252.     where type = 'P '
  253.             and name = 'sp_vupgrade_publisher')
  254.     drop procedure sp_vupgrade_publisher
  255.  
  256. if exists (select * from sysobjects
  257.     where type = 'P '
  258.             and name = 'sp_helppullsubscription')
  259.     drop procedure sp_helppullsubscription
  260.  
  261. if exists (select * from sysobjects
  262.     where type = 'P '
  263.             and name = 'sp_MSunmarkreplinfo')
  264.     drop procedure sp_MSunmarkreplinfo
  265.  
  266. if exists (select * from sysobjects
  267.     where type = 'P '
  268.             and name = 'sp_MSunmarkifneeded')
  269.     drop procedure sp_MSunmarkifneeded
  270.  
  271. if exists (select * from sysobjects
  272.         where type = 'P '
  273.                 and name = 'sp_MStable_has_unique_index')
  274.         drop procedure sp_MStable_has_unique_index
  275.  
  276. if exists (select * from sysobjects
  277.         where type = 'P '
  278.                 and name = 'sp_MSreplraiserror')
  279.         drop procedure sp_MSreplraiserror
  280.  
  281. if exists (select * from sysobjects
  282.         where type = 'P '
  283.                 and name = 'sp_check_sync_trigger')
  284.         drop procedure sp_check_sync_trigger
  285.  
  286. if exists (select * from sysobjects
  287.         where type = 'P '
  288.                 and name = 'sp_MSreplicationcompatlevel')
  289.     drop proc sp_MSreplicationcompatlevel    
  290.  
  291. if exists (select * from sysobjects
  292.         where type = 'P '
  293.                 and name = 'sp_MSgenreplnickname')
  294.     drop proc sp_MSgenreplnickname
  295.  
  296. if exists (select * from sysobjects
  297.         where type = 'P '
  298.                 and name = 'sp_MSenumallpublications')
  299.     drop proc sp_MSenumallpublications
  300.  
  301. if exists (select * from sysobjects
  302.         where type = 'P '
  303.                 and name = 'sp_MSenumtranpublications')
  304.     drop proc sp_MSenumtranpublications
  305.  
  306. if exists (select * from sysobjects
  307.         where type = 'P '
  308.                 and name = 'sp_MSenummergepublications')
  309.     drop proc sp_MSenummergepublications
  310.  
  311. if exists (select * from sysobjects
  312.         where type = 'P '
  313.                 and name = 'sp_MSenum3rdpartypublications')
  314.     drop proc sp_MSenum3rdpartypublications
  315.  
  316. if exists (select * from sysobjects
  317.                 where type = 'P' and
  318.                 name = 'sp_MSgetreplicainfo')
  319.         drop procedure sp_MSgetreplicainfo
  320.  
  321. if exists (select * from sysobjects
  322.     where type = 'P '
  323.            and name = 'sp_subscription_cleanup')
  324.      drop procedure sp_subscription_cleanup  
  325.  
  326. if exists (select * from sysobjects
  327.     where type = 'P '
  328.            and name = 'sp_mergesubscription_cleanup')
  329.      drop procedure sp_mergesubscription_cleanup  
  330.  
  331. if exists (select * from sysobjects
  332.     where type = 'P '
  333.             and name = 'sp_MSpad_command')
  334.     drop procedure sp_MSpad_command
  335.  
  336. if exists (select * from sysobjects
  337.     where type = 'P '
  338.             and name = 'sp_MSflush_command')
  339.     drop procedure sp_MSflush_command
  340.  
  341. if exists (select * from sysobjects
  342.     where type = 'P '
  343.             and name = 'sp_MSget_colinfo')
  344.     drop procedure sp_MSget_colinfo
  345.  
  346. if exists (select * from sysobjects
  347.     where type = 'P '
  348.             and name = 'sp_MSget_type')
  349.     drop procedure sp_MSget_type
  350.  
  351. if exists (select * from sysobjects
  352.     where type = 'P '
  353.             and name = 'sp_MSget_col_position')
  354.     drop procedure sp_MSget_col_position
  355.  
  356. if exists (select * from sysobjects
  357.     where type = 'P '
  358.             and name = 'sp_MSscript_where_clause')
  359.     drop procedure sp_MSscript_where_clause
  360.  
  361. if exists (select * from sysobjects
  362.     where type = 'P '
  363.             and name = 'sp_MSscript_params')
  364.     drop procedure sp_MSscript_params
  365.  
  366. if exists (select * from sysobjects
  367.     where type = 'P '
  368.             and name = 'sp_MSscript_begintrig1')
  369.     drop procedure sp_MSscript_begintrig1
  370.  
  371. if exists (select * from sysobjects
  372.     where type = 'P '
  373.             and name = 'sp_MSscript_begintrig2')
  374.     drop procedure sp_MSscript_begintrig2
  375.  
  376. if exists (select * from sysobjects
  377.     where type = 'P '
  378.             and name = 'sp_MSscript_endtrig')
  379.     drop procedure sp_MSscript_endtrig
  380.  
  381. if exists (select * from sysobjects
  382.     where type = 'P '
  383.             and name = 'sp_MSscript_trigger_variables')
  384.     drop procedure sp_MSscript_trigger_variables
  385.  
  386. if exists (select * from sysobjects
  387.     where type = 'P '
  388.             and name = 'sp_MSscript_trigger_assignment')
  389.     drop procedure sp_MSscript_trigger_assignment
  390.  
  391. if exists (select * from sysobjects
  392.     where type = 'P '
  393.             and name = 'sp_MSscript_trigger_fetch_statement')
  394.     drop procedure sp_MSscript_trigger_fetch_statement
  395.  
  396. if exists (select * from sysobjects
  397.     where type = 'P '
  398.             and name = 'sp_MSscript_trigger_exec_rpc')
  399.     drop procedure sp_MSscript_trigger_exec_rpc
  400.  
  401. if exists (select * from sysobjects
  402.     where type = 'P '
  403.             and name = 'sp_MSscript_trigger_update_checks')
  404.     drop procedure sp_MSscript_trigger_update_checks
  405.  
  406. if exists (select * from sysobjects
  407.     where type = 'P '
  408.             and name = 'sp_MSscript_trigger_updates')
  409.     drop procedure sp_MSscript_trigger_updates
  410.  
  411. if exists (select * from sysobjects
  412.     where type = 'P '
  413.             and name = 'sp_MSscript_singlerow_trigger')
  414.     drop procedure sp_MSscript_singlerow_trigger
  415.  
  416. if exists (select * from sysobjects
  417.     where type = 'P '
  418.             and name = 'sp_MSscript_multirow_trigger')
  419.     drop procedure sp_MSscript_multirow_trigger
  420.  
  421. if exists (select * from sysobjects
  422.     where type = 'P '
  423.             and name = 'sp_MSscript_sync_ins_trig')
  424.     drop procedure sp_MSscript_sync_ins_trig
  425.  
  426. if exists (select * from sysobjects
  427.     where type = 'P '
  428.             and name = 'sp_MSscript_sync_upd_trig')
  429.     drop procedure sp_MSscript_sync_upd_trig
  430.  
  431. if exists (select * from sysobjects
  432.     where type = 'P '
  433.             and name = 'sp_MSscript_sync_del_trig')
  434.     drop procedure sp_MSscript_sync_del_trig
  435.  
  436. if exists (select * from sysobjects
  437.     where type = 'P '
  438.             and name = 'sp_MSget_synctran_column')
  439.     drop procedure sp_MSget_synctran_column
  440.  
  441. if exists (select * from sysobjects
  442.     where type = 'P '
  443.             and name = 'sp_check_for_sync_trigger')
  444.     drop procedure sp_check_for_sync_trigger
  445.  
  446. if exists (select * from sysobjects
  447.     where type = 'P '
  448.             and name = 'sp_addsynctriggers')
  449.     drop procedure sp_addsynctriggers
  450.  
  451. if exists (select * from sysobjects
  452.         where type = 'P '
  453.             and name = 'sp_helpreplicationdboption')
  454.     drop procedure sp_helpreplicationdboption
  455.  
  456. if exists (select * from sysobjects
  457.         where type = 'P' and name = 'sp_MSgetreplnick')
  458.     drop procedure sp_MSgetreplnick
  459.         
  460. if exists (select * from sysobjects
  461.         where type = 'P' and name = 'sp_MStestbit')        
  462.     drop procedure sp_MStestbit
  463.         
  464. if exists (select * from sysobjects
  465.         where type = 'P' and name = 'sp_MSsetbit')
  466.     drop procedure sp_MSsetbit
  467.         
  468.         
  469. if exists (select * from sysobjects
  470.         where type = 'P' and name = 'sp_MSinsertcontents')
  471.     drop procedure sp_MSinsertcontents
  472.         
  473. if exists (select * from sysobjects
  474.         where type = 'P' and name = 'sp_MSupdatecontents')
  475.     drop procedure sp_MSupdatecontents
  476.             
  477. if exists (select * from sysobjects
  478.         where type = 'P' and name = 'sp_MSdeletecontents')
  479.     drop procedure sp_MSdeletecontents
  480.  
  481. if exists (select * from sysobjects
  482.         where type = 'P '
  483.             and name = 'sp_MSadd_repl_job')
  484.     drop procedure sp_MSadd_repl_job
  485.  
  486. IF EXISTS (select * from sysobjects where
  487.    name = 'sp_MScheck_agent_instance' and type = 'P')
  488.       DROP PROCEDURE sp_MScheck_agent_instance
  489.  
  490. if exists (select * from sysobjects
  491.         where name = 'xp_mergexpusage')
  492.     execute dbo.sp_dropextendedproc 'xp_mergexpusage'
  493.  
  494. if exists (select * from sysobjects 
  495.         where name = 'sp_get_distributor' 
  496.                 and type = 'P')
  497.       drop procedure sp_get_distributor
  498.  
  499. if exists (select * from sysobjects 
  500.         where name = 'sp_MSrepl_addrolemember' 
  501.                 and type = 'P')
  502.       drop procedure sp_MSrepl_addrolemember
  503.  
  504. if exists (select * from sysobjects 
  505.         where name = 'sp_MSrepl_droprolemember' 
  506.                 and type = 'P')
  507.       drop procedure sp_MSrepl_droprolemember
  508.  
  509. if exists (select * from sysobjects 
  510.         where name = 'sp_table_validation' 
  511.                 and type = 'P')
  512.       drop procedure sp_table_validation
  513.  
  514. if exists (select * from sysobjects 
  515.         where name = 'sp_MScreate_sub_tables' 
  516.                 and type = 'P')
  517.       drop procedure sp_MScreate_sub_tables
  518.  
  519. go
  520. if exists (select * from sysobjects 
  521.         where name = 'sp_removedbreplication' 
  522.                 and type = 'P')
  523.       drop procedure sp_removedbreplication
  524.  
  525. if exists (select * from sysobjects 
  526.         where name = 'sp_removesrvreplication' 
  527.                 and type = 'P')
  528.       drop procedure sp_removesrvreplication
  529.  
  530. if exists (select * from sysobjects 
  531.         where name = 'sp_vupgrade_subscription_databases' 
  532.                 and type = 'P')
  533.       drop procedure sp_vupgrade_subscription_databases
  534.  
  535. if exists (select * from sysobjects 
  536.         where name = 'sp_vupgrade_MSsubscription_properties' 
  537.                 and type = 'P')
  538.       drop procedure sp_vupgrade_MSsubscription_properties
  539.  
  540. if exists (select * from sysobjects 
  541.         where name = 'sp_vupgrade_mergetables' 
  542.                 and type = 'P')
  543.       drop procedure sp_vupgrade_mergetables
  544.  
  545. if exists (select * from sysobjects 
  546.         where name = 'sp_vupgrade_subscription_tables' 
  547.                 and type = 'P')
  548.       drop procedure sp_vupgrade_subscription_tables
  549.  
  550. if exists (select * from sysobjects 
  551.         where name = 'sp_vupgrade_replication' 
  552.                 and type = 'P')
  553.       drop procedure sp_vupgrade_replication
  554.  
  555. if exists (select * from sysobjects 
  556.         where name = 'sp_vupgrade_distdb' 
  557.                 and type = 'P')
  558.       drop procedure sp_vupgrade_distdb
  559.  
  560. if exists (select * from sysobjects 
  561.         where name = 'sp_vupgrade_replmsdb' 
  562.                 and type = 'P')
  563.       drop procedure sp_vupgrade_replmsdb
  564.  
  565. if exists (select * from sysobjects 
  566.         where name = 'sp_restoredbreplication' 
  567.                 and type = 'P')
  568.       drop procedure sp_restoredbreplication
  569.  
  570. if exists (select * from sysobjects 
  571.         where name = 'sp_MSget_publisher_rpc' 
  572.                 and type = 'P')
  573.       drop procedure sp_MSget_publisher_rpc
  574.  
  575. if exists (select * from sysobjects 
  576.         where name = 'sp_link_publication' 
  577.                 and type = 'P')
  578.       drop procedure sp_link_publication
  579.  
  580. if exists (select * from sysobjects 
  581.         where name = 'sp_MS_replication_installed' 
  582.                 and type = 'P')
  583.       drop procedure sp_MS_replication_installed
  584.  
  585. if exists (select * from sysobjects 
  586.         where name = 'sp_MSunc_to_drive' 
  587.                 and type = 'P')
  588.       drop procedure sp_MSunc_to_drive
  589.  
  590. if exists (select * from sysobjects 
  591.         where name = 'sp_MSdrop_object' 
  592.                 and type = 'P')
  593.       drop procedure sp_MSdrop_object
  594.  
  595. if exists (select * from sysobjects 
  596.         where name = 'sp_MSregistersubscription' 
  597.                 and type = 'P')
  598.       drop procedure sp_MSregistersubscription
  599.  
  600. if exists (select * from sysobjects 
  601.         where name = 'sp_MSunregistersubscription' 
  602.                 and type = 'P')
  603.       drop procedure sp_MSunregistersubscription
  604.  
  605. if exists (select * from sysobjects 
  606.         where name = 'sp_MSrepl_linkedservers_rowset' 
  607.                 and type = 'P')
  608.       drop procedure sp_MSrepl_linkedservers_rowset
  609.  
  610. if exists (select * from sysobjects 
  611.         where name = 'sp_MSrepl_isdbowner' 
  612.                 and type = 'P')
  613.       drop procedure sp_MSrepl_isdbowner
  614.  
  615. if exists (select * from sysobjects 
  616.         where name = 'sp_MSget_qualified_name' 
  617.                 and type = 'P')
  618.       drop procedure sp_MSget_qualified_name
  619.  
  620. if exists (select * from sysobjects 
  621.         where name = 'sp_MSscript_pkvar_assignment' 
  622.                 and type = 'P')
  623.       drop procedure sp_MSscript_pkvar_assignment
  624. go
  625.  
  626. if exists (select * from sysobjects 
  627.         where name = 'sp_MSget_jobstate' 
  628.                 and type = 'P')
  629.       drop procedure sp_MSget_jobstate
  630.  
  631. go
  632.  
  633. if exists (select * from sysobjects
  634.     where type = 'P '
  635.             and name = 'sp_MSget_publication_from_taskname')
  636.     drop procedure sp_MSget_publication_from_taskname
  637. go
  638.  
  639. if exists (select * from sysobjects
  640.     where type = 'P '
  641.             and name = 'sp_MSrepl_check_server')
  642.     drop procedure sp_MSrepl_check_server
  643. go
  644.  
  645. if exists (select * from sysobjects
  646.     where type = 'P '
  647.             and name = 'sp_MSreset_synctran_bit')
  648.     drop procedure sp_MSreset_synctran_bit
  649. go
  650.  
  651. sp_addextendedproc 'xp_mergexpusage', 'xprepl.dll'
  652. go
  653.  
  654. grant exec on xp_mergexpusage to public
  655. go
  656.  
  657. if exists (select * from sysobjects
  658.         where name = 'xp_showlineage')
  659.     execute dbo.sp_dropextendedproc 'xp_showlineage'
  660. go
  661.  
  662. sp_addextendedproc 'xp_showlineage', 'xprepl.dll'
  663. go
  664.  
  665. grant exec on xp_showlineage to public
  666. go
  667.  
  668. if exists (select * from sysobjects
  669.         where name = 'xp_updatelineage')
  670.     execute dbo.sp_dropextendedproc 'xp_updatelineage'
  671. go
  672.  
  673. sp_addextendedproc 'xp_updatelineage', 'xprepl.dll'
  674. go
  675.  
  676. grant exec on xp_updatelineage to public
  677. go
  678.  
  679. if exists (select * from sysobjects
  680.         where name = 'xp_proxiedmetadata')
  681.     execute dbo.sp_dropextendedproc 'xp_proxiedmetadata'
  682. go
  683.  
  684. sp_addextendedproc 'xp_proxiedmetadata', 'xprepl.dll'
  685. go
  686.  
  687. grant exec on xp_proxiedmetadata to public
  688. go
  689.  
  690. if exists (select * from sysobjects
  691.         where name = 'xp_initcolvs')
  692.     execute dbo.sp_dropextendedproc 'xp_initcolvs'
  693. go
  694.  
  695. sp_addextendedproc 'xp_initcolvs', 'xprepl.dll'
  696. go
  697. grant exec on xp_initcolvs to public
  698. go
  699.  
  700. if exists (select * from sysobjects
  701.         where name = 'xp_updatecolvbm')
  702.     execute dbo.sp_dropextendedproc 'xp_updatecolvbm'
  703. go
  704.  
  705. sp_addextendedproc 'xp_updatecolvbm', 'xprepl.dll'
  706. go
  707.  
  708. grant exec on xp_updatecolvbm to public
  709. go
  710.  
  711. if exists (select * from sysobjects
  712.         where name = 'xp_showcolv')
  713.     execute dbo.sp_dropextendedproc 'xp_showcolv'
  714. go
  715.  
  716. sp_addextendedproc 'xp_showcolv', 'xprepl.dll'
  717. go
  718.  
  719. grant exec on xp_showcolv to public
  720. go
  721.  
  722. if exists (select * from sysobjects
  723.         where name = 'xp_execresultset')
  724.     execute dbo.sp_dropextendedproc 'xp_execresultset'
  725. go
  726.  
  727. sp_addextendedproc 'xp_execresultset', 'xprepl.dll'
  728. go
  729.  
  730. grant exec on xp_execresultset to public
  731. go
  732.  
  733. if exists (select * from sysobjects
  734.         where name = 'xp_varbintohexstr')
  735.     execute dbo.sp_dropextendedproc 'xp_varbintohexstr'
  736. go
  737.  
  738. sp_addextendedproc 'xp_varbintohexstr', 'xprepl.dll'
  739. go
  740.  
  741. grant exec on xp_varbintohexstr to public
  742. go
  743.  
  744. if exists (select * from sysobjects
  745.         where name = 'xp_intersectbitmaps')
  746.     execute dbo.sp_dropextendedproc 'xp_intersectbitmaps'
  747. go
  748.  
  749. sp_addextendedproc 'xp_intersectbitmaps', 'xprepl.dll'
  750. go
  751.  
  752. grant exec on xp_intersectbitmaps to public
  753. go
  754.  
  755. if exists (select * from sysobjects
  756.         where name = 'xp_displayparamstmt')
  757.     execute dbo.sp_dropextendedproc 'xp_displayparamstmt'
  758. go
  759.  
  760. sp_addextendedproc 'xp_displayparamstmt', 'xprepl.dll'
  761. go
  762.  
  763. grant exec on xp_displayparamstmt to public
  764. go
  765.  
  766.  
  767. if exists (select * from sysobjects
  768.         where name = 'xp_printstatements')
  769.     execute dbo.sp_dropextendedproc 'xp_printstatements'
  770. go
  771.  
  772. sp_addextendedproc 'xp_printstatements', 'xprepl.dll'
  773. go
  774.  
  775. grant exec on xp_printstatements to public
  776. go
  777.  
  778.  
  779.  
  780.  
  781. /* Create table dbo.MSreplication_options */
  782. IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSreplication_options'
  783.     and type = 'U')
  784. BEGIN
  785.     raiserror('Creating procedure Creating table MSreplication_options',0,1)
  786.     
  787.  
  788.     CREATE TABLE dbo.MSreplication_options 
  789.     (
  790.     optname            sysname NOT NULL,
  791.     value            bit NOT NULL,
  792.     major_version    int NOT NULL,
  793.     minor_version    int NOT NULL,
  794.     revision        int NOT NULL,
  795.     install_failures int NOT NULL
  796.     )
  797. END
  798. GO
  799.  
  800. IF NOT EXISTS ( SELECT * FROM sysindexes where name = 'ucMSreplication_options' and 
  801.                 id = OBJECT_ID('MSreplication_options'))
  802. CREATE UNIQUE CLUSTERED INDEX ucMSreplication_options ON MSreplication_options(optname)
  803. GO
  804.  
  805.  
  806. IF NOT EXISTS (SELECT * FROM MSreplication_options WHERE optname = 'transactional')
  807.     INSERT INTO MSreplication_options VALUES
  808.         ('transactional',0,0,0,0,0)
  809. IF NOT EXISTS (SELECT * FROM MSreplication_options WHERE optname = 'merge')
  810.     INSERT INTO MSreplication_options VALUES
  811.         ('merge',0,0,0,0,0)
  812. GO
  813.  
  814. raiserror('Creating procedure sp_MSreplcheck_name', 0,1)
  815. GO
  816.  
  817. CREATE PROCEDURE sp_MSreplcheck_name
  818.     @name            sysname,
  819.     @raise_error    bit = 1
  820. AS
  821.     declare @index    int
  822.  
  823.     Set nocount on
  824.  
  825.     -- Name cannot be NULL or empty ("")
  826.     -- Blank identifiers (" ") are allowed
  827.     IF (@name is null OR datalength(@name) = 0)
  828.     begin
  829.         if @raise_error = 1
  830.             raiserror (15004,16,-1)
  831.         return (1)
  832.     end
  833.  
  834.     -- Check for proscribed characters
  835.  
  836.     declare @length int
  837.     select @length = datalength( @name ) / 2
  838.     select @index = 1
  839.     while @index < @length
  840.     begin
  841.         if( 0 = unicode( substring( @name, @index, 1 ) ) )
  842.         begin
  843.             if @raise_error = 1
  844.                 raiserror(15006,16,-1,@name)
  845.             return (1)
  846.         end
  847.  
  848.         select @index = @index + 1
  849.     end
  850.  
  851.     --check for other proscribed characters
  852.  
  853.     select @index = charindex( N'%', @name)
  854.     if (@index <> 0)
  855.     begin
  856.         if @raise_error = 1
  857.             raiserror(15006,16,-1,@name)
  858.         return (1)
  859.     end
  860.     select @index = charindex(N'*', @name)
  861.     if (@index <> 0)
  862.     begin
  863.         if @raise_error = 1
  864.             raiserror(15006,16,-1,@name)
  865.         return (1)
  866.     end
  867.     select @index = charindex(N'[', @name)
  868.     if (@index <> 0)
  869.     begin
  870.         if @raise_error = 1
  871.             raiserror(15006,16,-1,@name)
  872.         return (1)
  873.     end
  874.     select @index = charindex(N']', @name)
  875.     if (@index <> 0)
  876.     begin
  877.         if @raise_error = 1
  878.             raiserror(15006,16,-1,@name)
  879.         return (1)
  880.     end
  881.     select @index = charindex(N'|', @name)
  882.     if (@index <> 0)
  883.     begin
  884.         if @raise_error = 1
  885.             raiserror(15006,16,-1,@name)
  886.         return (1)
  887.     end
  888.     select @index = charindex(N':', @name)
  889.     if (@index <> 0)
  890.     begin
  891.         if @raise_error = 1
  892.             raiserror(15006,16,-1,@name)
  893.         return (1)
  894.     end
  895.     select @index = charindex(N'"', @name)
  896.     if (@index <> 0)
  897.     begin
  898.         if @raise_error = 1
  899.             raiserror(15006,16,-1,@name)
  900.         return (1)
  901.     end
  902.     select @index = charindex(N'?', @name)
  903.     if (@index <> 0)
  904.     begin
  905.         if @raise_error = 1
  906.             raiserror(15006,16,-1,@name)
  907.         return (1)
  908.     end
  909.     /*
  910.     ** Fix 52855 - allow single quote
  911.     **
  912.     select @index = charindex(N'''', @name)
  913.     if (@index <> 0)
  914.     begin
  915.         if @raise_error = 1
  916.             raiserror(15006,16,-1,@name)
  917.         return (1)
  918.     end
  919.     */
  920.     select @index = charindex(N'\', @name)
  921.     if (@index <> 0)
  922.     begin
  923.         if @raise_error = 1
  924.             raiserror(15006,16,-1,@name)
  925.         return (1)
  926.     end
  927.     select @index = charindex(N'/', @name)
  928.     if (@index <> 0)
  929.     begin
  930.         if @raise_error = 1
  931.             raiserror(15006,16,-1,@name)
  932.         return (1)
  933.     end
  934.     select @index = charindex(N'<', @name)
  935.     if (@index <> 0)
  936.     begin
  937.         if @raise_error = 1
  938.             raiserror(15006,16,-1,@name)
  939.         return (1)
  940.     end
  941.     select @index = charindex(N'>', @name)
  942.     if (@index <> 0)
  943.     begin
  944.         if @raise_error = 1
  945.             raiserror(15006,16,-1,@name)
  946.         return (1)
  947.     end
  948.     
  949.     -- return success
  950.  
  951.     return (0) 
  952. GO
  953.     
  954.  
  955. exec dbo.sp_MS_marksystemobject sp_MSreplcheck_name
  956. go
  957.  
  958.  
  959.  
  960. raiserror('Creating procedure sp_MScheckvalidsystables', 0,1)
  961. GO
  962.  
  963. create procedure sp_MScheckvalidsystables  @validsubs int output
  964. AS
  965.     if not exists (select name from sysobjects where name='sysmergesubscriptions')
  966.         begin
  967.         set @validsubs = 0
  968.         return
  969.         end
  970.  
  971.     /* Is there a valid non-loopback subscription? */
  972.     if exists (select * from sysmergesubscriptions
  973.         where db_name=db_name() and srvid = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@@servername))
  974.         and subid <> partnerid)
  975.         begin
  976.         set @validsubs = 1
  977.         return
  978.         end
  979.     /* Only possible subscriptions are loopbacks.  If database not enabled for publishing,
  980.     ** then they don't indicate a valid publication/subscription. */
  981.     if not exists (select name from master..sysdatabases where
  982.         (category & 4) = 4 and name = db_name())
  983.         begin
  984.         set @validsubs = 0
  985.         return
  986.         end
  987.     /* Database has merge publishing turned on, is probably a publisher.  Look for loopback
  988.     ** subscription just to be sure... */
  989.     if exists (select * from sysmergesubscriptions
  990.         where db_name=db_name() and srvid = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@@servername)))
  991.         begin
  992.         set @validsubs = 1
  993.         return
  994.         end
  995.         
  996.     /* Must not be valid... */    
  997.     set @validsubs = 0
  998.     return
  999.  
  1000.  
  1001. GO
  1002.  
  1003.  
  1004. raiserror('Creating procedure sp_MSdrop_mergesystables', 0,1)
  1005. GO
  1006. create procedure sp_MSdrop_mergesystables as
  1007.  
  1008.     begin tran
  1009.     save transaction drop_mergesystables
  1010.     if exists (select * from sysobjects
  1011.         where name = 'sysmergearticles')
  1012.         begin
  1013.         drop table sysmergearticles
  1014.         end
  1015.     if @@error<>0
  1016.         goto Error
  1017.  
  1018.     if exists (select * from sysobjects
  1019.         where name = 'sysmergepublications')
  1020.         begin
  1021.         drop table sysmergepublications
  1022.         end
  1023.     if @@error<>0
  1024.         goto Error
  1025.  
  1026.     if exists (select * from sysobjects
  1027.         where name = 'sysmergesubscriptions')
  1028.         begin
  1029.         drop table sysmergesubscriptions
  1030.         end
  1031.     if @@error<>0
  1032.         goto Error
  1033.         
  1034.     if exists (select * from sysobjects
  1035.         where name = 'MSmerge_contents')
  1036.         begin
  1037.         drop table MSmerge_contents
  1038.         end
  1039.     if @@error<>0
  1040.         goto Error
  1041.  
  1042.     if exists (select * from sysobjects
  1043.         where name = 'MSmerge_replinfo')
  1044.         begin
  1045.         drop table MSmerge_replinfo
  1046.         end
  1047.     if @@error<>0
  1048.         goto Error
  1049.         
  1050.     if exists (select * from sysobjects
  1051.         where name = 'MSmerge_tombstone')
  1052.         begin
  1053.         drop table MSmerge_tombstone
  1054.         end
  1055.     if @@error<>0
  1056.         goto Error
  1057.         
  1058.     if exists (select * from sysobjects
  1059.         where name = 'MSmerge_genhistory')
  1060.         begin
  1061.         drop table MSmerge_genhistory
  1062.         end
  1063.     if @@error<>0
  1064.         goto Error
  1065.         
  1066.     if exists (select * from sysobjects
  1067.         where name = 'MSmerge_delete_conflicts')
  1068.         begin
  1069.         drop table MSmerge_delete_conflicts
  1070.         end
  1071.     if @@error<>0
  1072.         goto Error
  1073.  
  1074.     if exists (select * from sysobjects
  1075.         where name = 'sysmergeschemachange')
  1076.         begin
  1077.         drop table sysmergeschemachange
  1078.         end
  1079.     if @@error<>0
  1080.         goto Error
  1081.  
  1082.     if exists (select * from sysobjects
  1083.         where name = 'sysmergesubsetfilters')
  1084.         begin
  1085.         drop table sysmergesubsetfilters
  1086.         end
  1087.     if @@error<>0
  1088.         goto Error
  1089.  
  1090.     commit transaction    
  1091.     return 0
  1092. Error:
  1093.     RAISERROR (20007, 16, -1)
  1094.     if @@trancount > 0
  1095.     begin
  1096.         ROLLBACK TRANSACTION drop_mergesystables
  1097.         COMMIT TRANSACTION
  1098.     end
  1099.     return 1
  1100. go
  1101.  
  1102. exec dbo.sp_MS_marksystemobject sp_MSdrop_mergesystables
  1103. go
  1104.  
  1105. raiserror ('Executing procedure dbo.sp_MSdrop_mergesystables.',0,1)
  1106. go
  1107. exec dbo.sp_MSdrop_mergesystables
  1108. go
  1109.  
  1110. dump tran master with no_log
  1111. go
  1112.  
  1113. raiserror('Creating procedure sp_MScreate_mergesystables',0,1)
  1114. GO
  1115. create procedure sp_MScreate_mergesystables as
  1116.  
  1117.     /* This is to make sure that the varbinary columns do not get padded */
  1118.  
  1119.     set ANSI_PADDING off
  1120.  
  1121.     DECLARE @exist bit 
  1122.     DECLARE @validsubs  int
  1123.     select @exist = 1
  1124.     
  1125.     begin tran
  1126.     save transaction MScreate_mergesystables
  1127.  
  1128.     exec dbo.sp_MScheckvalidsystables  @validsubs  output
  1129.     if @validsubs = 0
  1130.         exec dbo.sp_MSdrop_mergesystables
  1131.         
  1132.     if not exists (select * from sysobjects where name = 'sysmergepublications')
  1133.         begin
  1134.  
  1135.             raiserror('Creating table sysmergepublications',0,1)
  1136.             
  1137.             create table dbo.sysmergepublications
  1138.             (    publisher                sysname NOT NULL default @@servername,
  1139.                 publisher_db            sysname NOT NULL default db_name(),
  1140.                 name                    sysname                NOT NULL,
  1141.                 description                nvarchar(255)         NULL,
  1142.                 retention                int                    NULL,
  1143.                 publication_type         tinyint                NULL,
  1144.                 pubid                     uniqueidentifier     NOT NULL,
  1145.                 designmasterid            uniqueidentifier     NULL,
  1146.                 parentid                uniqueidentifier     NULL,
  1147.                 sync_mode                tinyint                NULL,
  1148.                 allow_push                int                    NULL,
  1149.                 allow_pull                int                    NULL,
  1150.                 allow_anonymous            int                    NULL,
  1151.                 centralized_conflicts    int                    NULL,
  1152.                 status                    tinyint                NULL,
  1153.                 snapshot_ready            tinyint                NULL,
  1154.                 enabled_for_internet    bit                    NOT NULL default 0,
  1155.                 dynamic_filters            bit                    NOT NULL default 0,
  1156.                 keep_before_values            int                NULL default 0
  1157.  
  1158.             )
  1159.             if @@ERROR <> 0
  1160.                 goto Error
  1161.             else
  1162.                 begin
  1163.                     create unique nonclustered index nc1sysmergepublications
  1164.                         on sysmergepublications(pubid) 
  1165.                     if @@ERROR <> 0
  1166.                         goto Error
  1167.                 end
  1168.             
  1169.             exec dbo.sp_MS_marksystemobject sysmergepublications
  1170.             if @@ERROR <> 0
  1171.                 goto Error
  1172.             grant select on sysmergepublications to public
  1173.         end
  1174.  
  1175.  
  1176.     if not exists (select * from sysobjects where name = 'sysmergearticles')
  1177.         begin
  1178.         
  1179.             raiserror('Creating table sysmergearticles',0,1)
  1180.  
  1181.             
  1182.             create table dbo.sysmergearticles (
  1183.                 name                    sysname                NOT NULL,
  1184.                 type                    tinyint                NULL,
  1185.                 objid                    int                    NOT NULL,
  1186.                 sync_objid                int                    NOT NULL,
  1187.                 view_type                 tinyint                NULL,
  1188.                 artid                    uniqueidentifier    NOT NULL,
  1189.                 description                nvarchar(255)        NULL,
  1190.                 pre_creation_command    tinyint                NULL,
  1191.                 pubid                    uniqueidentifier     NOT NULL,
  1192.                 nickname                int                    NOT NULL,
  1193.                 column_tracking            int                    NOT NULL,
  1194.                 status                    tinyint                NULL,
  1195.                 conflict_table            sysname                NULL,
  1196.                 creation_script            nvarchar(255)        NULL,
  1197.                 conflict_script            nvarchar(255)        NULL,
  1198.                 article_resolver        nvarchar(255)        NULL,
  1199.                 ins_conflict_proc        sysname                NULL,
  1200.                 insert_proc                sysname                NULL,
  1201.                 update_proc                sysname                NULL,
  1202.                 select_proc                sysname                NULL,
  1203.                 schema_option             binary(8)             NULL,
  1204.                 destination_object        sysname                NOT NULL,
  1205.                 resolver_clsid            nvarchar(50)        NULL,
  1206.                 subset_filterclause        nvarchar(1000)      NULL,
  1207.                 missing_col_count        int                    NULL,
  1208.                 missing_cols            varbinary(128)        NULL,
  1209.                 columns                    varbinary(128)       NULL,
  1210.                 resolver_info            nvarchar(255)        NULL,
  1211.                 view_sel_proc            nvarchar(290)        NULL,
  1212.                 gen_cur                    int                    NULL,
  1213.                 before_image_objid        int                    NULL,
  1214.                 before_view_objid        int                    NULL
  1215.  
  1216.             )
  1217.         
  1218.             if @@error<>0
  1219.                 goto Error
  1220.             else
  1221.                 begin
  1222.                     create unique clustered index uc1sysmergearticles
  1223.                         on sysmergearticles(artid, pubid) 
  1224.                     if @@ERROR <> 0
  1225.                         goto Error
  1226.                 end
  1227.             exec dbo.sp_MS_marksystemobject sysmergearticles
  1228.             if @@ERROR <> 0
  1229.                 goto Error
  1230.             grant select on sysmergearticles to public
  1231.             
  1232.         end
  1233.  
  1234.     if not exists (select * from sysobjects    where name = 'sysmergesubscriptions')
  1235.         begin
  1236.         
  1237.             raiserror('Creating table sysmergesubscriptions',0,1)
  1238.  
  1239.             
  1240.             create table dbo.sysmergesubscriptions
  1241.             (
  1242.                 subid                 uniqueidentifier     NOT NULL,
  1243.                 partnerid             uniqueidentifier     NOT NULL,
  1244.                 datasource_type        int                    NOT NULL,
  1245.                 datasource_path        nvarchar(255)        NULL,
  1246.                 srvid                 int                    NOT NULL,
  1247.                 db_name                  sysname                 NOT NULL
  1248.                 constraint             unique_pubsrvdb     unique nonclustered (pubid, srvid, db_name),
  1249.                 pubid                uniqueidentifier     NULL,
  1250.                 status                tinyint             NOT NULL,
  1251.                 subscriber_type        int                    NOT NULL,
  1252.                 subscription_type    int                    NOT NULL,
  1253.                 priority            real                NOT NULL,
  1254.                 sync_type             tinyint                NOT NULL,    -- 1 = automatic 2 = no sync
  1255.                 description            nvarchar(255)        NULL,
  1256.                 login_name            sysname                NOT NULL,
  1257.                 last_validated        datetime            NULL
  1258.             )
  1259.         
  1260.             if @@error<>0
  1261.                 goto Error
  1262.             else
  1263.                 begin
  1264.                     create unique clustered index uc1sysmergesubscriptions 
  1265.                         on sysmergesubscriptions (subid) 
  1266.                     if @@ERROR<>0
  1267.                         goto Error
  1268.                 end
  1269.             exec dbo.sp_MS_marksystemobject sysmergesubscriptions
  1270.             if @@ERROR <> 0
  1271.                 goto Error
  1272.             grant select on sysmergesubscriptions to public
  1273.             
  1274.         end
  1275.  
  1276.     if not exists (select * from sysobjects    where name = 'MSmerge_replinfo')
  1277.         begin
  1278.             raiserror('Creating table MSmerge_replinfo',0,1)
  1279.             
  1280.             create table dbo.MSmerge_replinfo
  1281.             (
  1282.                 repid                     uniqueidentifier     NOT NULL,
  1283.                 replnickname            int                    NOT NULL,
  1284.                 recgen                    int                 NULL,
  1285.                 recguid                    uniqueidentifier     NULL,
  1286.                 sentgen                    int                 NULL,
  1287.                 sentguid                uniqueidentifier     NULL,
  1288.                 schemaversion            int                 NULL,
  1289.                 schemaguid                uniqueidentifier     NULL,
  1290.                 merge_jobid                binary(16)            NULL,
  1291.                 snapshot_jobid            binary(16)            NULL
  1292.             )
  1293.         
  1294.             if @@ERROR <> 0
  1295.                 goto Error
  1296.             else
  1297.                 begin
  1298.                     create unique clustered index uc1MSmerge_replinfo
  1299.                         on MSmerge_replinfo (repid)
  1300.                     if @@ERROR <> 0
  1301.                         goto Error
  1302.                 end
  1303.             exec dbo.sp_MS_marksystemobject MSmerge_replinfo
  1304.             if @@ERROR <> 0
  1305.                 goto Error
  1306.             grant select on MSmerge_replinfo to public
  1307.             
  1308.         end
  1309.  
  1310.     if not exists (select * from sysobjects    where name = 'MSmerge_tombstone')
  1311.         begin
  1312.             raiserror('Creating table MSmerge_tombstone',0,1)
  1313.             
  1314.             create table dbo.MSmerge_tombstone
  1315.             (
  1316.                 rowguid            uniqueidentifier rowguidcol NOT NULL,
  1317.                 tablenick        int                NOT NULL,
  1318.                 type            tinyint            NOT NULL,
  1319.                 lineage            varbinary(255)    NOT NULL,
  1320.                 generation        int                NOT NULL,
  1321.                 reason            nvarchar(255)    NOT NULL,
  1322.             )
  1323.  
  1324.             if @@ERROR <> 0
  1325.                 goto Error
  1326.             else
  1327.                 begin
  1328.                     create unique clustered index uc1MSmerge_tombstone
  1329.                         on MSmerge_tombstone (tablenick, rowguid) 
  1330.                     if @@ERROR <> 0
  1331.                         goto Error
  1332.                     create index nc2MSmerge_tombstone
  1333.                         on MSmerge_tombstone (generation) 
  1334.                     if @@ERROR <> 0
  1335.                         goto Error
  1336.                 end    
  1337.              exec dbo.sp_MS_marksystemobject MSmerge_tombstone
  1338.              if @@ERROR <> 0
  1339.                 goto Error
  1340.             grant select on MSmerge_tombstone to public
  1341.             
  1342.         end
  1343.  
  1344.     if not exists (select * from sysobjects    where name = 'MSmerge_contents')
  1345.         begin
  1346.             raiserror('Creating table MSmerge_contents',0,1)
  1347.             
  1348.             create table dbo.MSmerge_contents
  1349.             (
  1350.                 tablenick        int                    NOT NULL,
  1351.                 rowguid            uniqueidentifier rowguidcol   NOT NULL,
  1352.                 generation        int                    NOT NULL,
  1353.                 partchangegen    int                    NULL,
  1354.                 joinchangegen    int                    NULL,
  1355.                 lineage            varbinary(249)        NOT NULL,
  1356.                 colv1            varbinary(2048)        NULL,
  1357.             )
  1358.         
  1359.             if @@ERROR <> 0
  1360.                 goto Error
  1361.             else
  1362.                 begin
  1363.                     create unique clustered index uc1SycContents on MSmerge_contents( tablenick, rowguid )
  1364.                     if @@ERROR <> 0
  1365.                         goto Error
  1366.                     create index nc2MSmerge_contents on MSmerge_contents(tablenick, generation) 
  1367.                     if @@ERROR <> 0
  1368.                         goto Error
  1369.                     create index nc3MSmerge_contents on MSmerge_contents(tablenick, partchangegen) 
  1370.                     if @@ERROR <> 0
  1371.                         goto Error
  1372.                     create index nc4MSmerge_contents on MSmerge_contents(generation, partchangegen) 
  1373.                     if @@ERROR <> 0
  1374.                         goto Error
  1375.                 end
  1376.             exec dbo.sp_MS_marksystemobject MSmerge_contents
  1377.             if @@ERROR <> 0
  1378.                 goto Error
  1379.             grant select on MSmerge_contents to public
  1380.             
  1381.         end                
  1382.  
  1383.     if not exists (select * from sysobjects    where name = 'MSmerge_genhistory')
  1384.         begin
  1385.             raiserror('Creating table MSmerge_genhistory',0,1)
  1386.             
  1387.             create table dbo.MSmerge_genhistory
  1388.             (
  1389.                 guidsrc         uniqueidentifier     NOT NULL,
  1390.                 guidlocal         uniqueidentifier     NOT NULL,
  1391.                 pubid            uniqueidentifier     NULL,
  1392.                 generation         int                    NOT NULL,
  1393.                 art_nick        int                    NULL,
  1394.                 nicknames        varbinary(255)        NOT NULL,
  1395.                 coldate         datetime            NOT NULL
  1396.             )
  1397.         
  1398.             if @@ERROR <> 0
  1399.                 goto Error
  1400.             create clustered index uc1MSmerge_genhistory on MSmerge_genhistory(guidsrc) 
  1401.             if @@ERROR <> 0
  1402.                 goto Error
  1403.  
  1404.             create  index nc1MSmerge_genhistory on MSmerge_genhistory(generation) 
  1405.             if @@ERROR <> 0
  1406.                 goto Error
  1407.  
  1408.             create  index nc2MSmerge_genhistory on MSmerge_genhistory(guidlocal) 
  1409.             if @@ERROR <> 0
  1410.                 goto Error
  1411.  
  1412.             create  unique index nc3MSmerge_genhistory on MSmerge_genhistory(guidsrc, pubid)
  1413.             if @@ERROR <> 0
  1414.                 goto Error
  1415.  
  1416.             create  index nc4MSmerge_genhistory on MSmerge_genhistory(coldate) 
  1417.             if @@ERROR <> 0
  1418.                 goto Error
  1419.  
  1420.              exec dbo.sp_MS_marksystemobject MSmerge_genhistory
  1421.              if @@ERROR <> 0
  1422.                 goto Error
  1423.             grant select on MSmerge_genhistory to public
  1424.             
  1425.         end
  1426.  
  1427.     if not exists (select * from sysobjects    where name = 'MSmerge_delete_conflicts')
  1428.         begin
  1429.  
  1430.             raiserror('Creating table MSmerge_delete_conflicts',0,1)
  1431.             
  1432.             create table dbo.MSmerge_delete_conflicts
  1433.             (
  1434.                 tablenick            int                NOT NULL,
  1435.                 rowguid                uniqueidentifier rowguidcol NOT NULL,
  1436.                 origin_datasource    nvarchar(255)    NULL,
  1437.                 conflict_type        int NULL,
  1438.                 reason_code            int NULL,
  1439.                 reason_text            nvarchar(720)     NULL,
  1440.                 pubid                uniqueidentifier NULL
  1441.             )
  1442.         
  1443.             if @@ERROR <> 0
  1444.                 goto Error
  1445.             else
  1446.                 begin
  1447.                     create clustered index uc1MSmerge_delete_conflicts on MSmerge_delete_conflicts(tablenick, rowguid) 
  1448.                     if @@ERROR <> 0
  1449.                         goto Error
  1450.                 end    
  1451.  
  1452.             create  unique index nc1MSmerge_delete_conflicts on MSmerge_delete_conflicts(tablenick, rowguid, origin_datasource)
  1453.             if @@ERROR <> 0
  1454.                 goto Error    
  1455.                                 
  1456.             exec dbo.sp_MS_marksystemobject MSmerge_delete_conflicts
  1457.             if @@ERROR <> 0
  1458.                 goto Error
  1459.             grant select on MSmerge_delete_conflicts to public
  1460.             
  1461.         end
  1462.  
  1463.     if not exists (select * from sysobjects    where name = 'sysmergeschemachange')
  1464.         begin
  1465.         
  1466.             raiserror('Creating table sysmergeschemachange',0,1)
  1467.             
  1468.             create table dbo.sysmergeschemachange
  1469.             (
  1470.                 pubid            uniqueidentifier     NOT NULL,
  1471.                 artid            uniqueidentifier     NULL,
  1472.                 schemaversion     int                    NOT NULL,
  1473.                 schemaguid        uniqueidentifier     NOT NULL,
  1474.                 schematype        int                      NOT NULL,
  1475.                 schematext        nvarchar(2000)         NOT NULL
  1476.             )
  1477.         
  1478.             if @@ERROR <> 0
  1479.                 goto Error
  1480.             else
  1481.                 begin
  1482.                     create unique clustered index schemachangeversion on sysmergeschemachange(schemaversion, pubid) 
  1483.                     if @@ERROR <> 0
  1484.                         goto Error
  1485.                 end
  1486.  
  1487.             exec dbo.sp_MS_marksystemobject sysmergeschemachange
  1488.             if @@ERROR <> 0
  1489.                 goto Error
  1490.             grant select on sysmergeschemachange to public
  1491.             
  1492.         end
  1493.  
  1494.     if not exists (select * from sysobjects where name = 'sysmergesubsetfilters')
  1495.         begin
  1496.             raiserror('Creating table sysmergesubsetfilters',0,1)
  1497.  
  1498.             
  1499.             create table dbo.sysmergesubsetfilters (
  1500.                 filtername              sysname                 NOT NULL,
  1501.                 join_filterid            int                    identity NOT NULL,
  1502.                 pubid                    uniqueidentifier    NOT NULL,
  1503.                 artid                    uniqueidentifier    NOT NULL,
  1504.                 art_nickname            int                    NOT NULL,
  1505.                 join_articlename        sysname NOT NULL,
  1506.                 join_nickname             int                    NOT NULL,
  1507.                 join_unique_key            int                    NOT NULL,
  1508.                 expand_proc                sysname                    NULL,
  1509.                 join_filterclause        nvarchar(1000)          NULL
  1510.             )
  1511.             if @@ERROR <> 0
  1512.                 goto Error
  1513.             else 
  1514.                 begin 
  1515.                     create unique index nc1sysmergesubsetfilters on sysmergesubsetfilters(join_filterid, pubid)
  1516.                         if @@ERROR <> 0
  1517.                         goto Error
  1518.                 end
  1519.  
  1520.             exec dbo.sp_MS_marksystemobject sysmergesubsetfilters
  1521.             if @@ERROR <> 0
  1522.                 goto Error
  1523.             grant select on sysmergesubsetfilters to public
  1524.             
  1525.         end
  1526.  
  1527.         if @@error <> 0
  1528.             return(1)
  1529.  
  1530.     commit transaction
  1531.     return (0)
  1532. Error:
  1533.     if @@trancount > 0
  1534.     begin
  1535.         ROLLBACK TRANSACTION MScreate_mergesystables
  1536.         COMMIT TRANSACTION
  1537.     end
  1538.     RAISERROR (20008, 16, -1)
  1539.     return (1)
  1540. go
  1541.  
  1542. exec dbo.sp_MS_marksystemobject sp_MScreate_mergesystables 
  1543. go
  1544.  
  1545. raiserror('Creating procedure sp_MStestbit',0,1)
  1546. go
  1547. create procedure sp_MStestbit
  1548.             @bm varbinary(125),
  1549.             @coltotest smallint
  1550. AS
  1551.             declare @word smallint
  1552.             declare @bit  smallint
  1553.             declare @mask binary(2)
  1554.             declare @mval int
  1555.             declare @oldword binary(2)  
  1556.  
  1557.             if @coltotest < 1 return 0
  1558.  
  1559.             SELECT @word = CONVERT(smallint, 1 + FLOOR((@coltotest -1)/16))
  1560.  
  1561.             SELECT @bit = (@coltotest -1) % 16
  1562.  
  1563.             SELECT @mval = POWER(2, @bit)
  1564.             SELECT @mask = convert( binary(2), unicode( substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) ) )
  1565.             
  1566.             SELECT @oldword = convert( binary(2), SUBSTRING( convert( nvarchar(63),@bm), @word, 1) )
  1567.             IF @oldword IS NULL return 0
  1568.  
  1569.             return  convert( smallint, @oldword ) & convert( smallint, @mask )
  1570. go
  1571. exec dbo.sp_MS_marksystemobject sp_MStestbit
  1572. go
  1573. grant exec on dbo.sp_MStestbit to public
  1574.         
  1575.         
  1576. raiserror('Creating procedure sp_MSsetbit',0,1)
  1577. go
  1578. create procedure sp_MSsetbit
  1579.                 @bm varbinary(125) output,
  1580.                 @coltoadd smallint
  1581. AS
  1582.             declare @word smallint
  1583.             declare @bit smallint
  1584.             declare @mask binary(2)
  1585.             declare @mval int
  1586.             declare @newword binary(2)     
  1587.             declare @oldword binary(2) 
  1588.  
  1589.             SELECT @word = CONVERT(smallint, 1 + FLOOR((@coltoadd-1)/16))
  1590.  
  1591.             IF @word > 62 return 0
  1592.  
  1593.             SELECT @bit = (@coltoadd-1) % 16
  1594.  
  1595.             SET @mval = POWER(2, @bit)
  1596.             SELECT @mask = convert( binary(2), unicode( substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) ) )
  1597.  
  1598.             if @bm is null
  1599.                 set @bm = 0x0
  1600.             while datalength(@bm) < @word * 2
  1601.                 set @bm = @bm + 0x0000
  1602.  
  1603.             SET @oldword = convert( binary(2), SUBSTRING( convert(nvarchar(63),@bm), @word, 1) )
  1604.             IF @oldword IS NULL SET @oldword = 0x00
  1605.  
  1606.             SET @newword = convert( smallint, @oldword) | convert( smallint, @mask )
  1607.  
  1608.             SET @bm = CONVERT(varbinary(125), STUFF( CONVERT(nvarchar(63),@bm), @word, 1, convert( nchar(1),@newword)) )
  1609. go            
  1610. exec dbo.sp_MS_marksystemobject sp_MSsetbit
  1611. go
  1612. grant exec on dbo.sp_MSsetbit to public
  1613.  
  1614. raiserror('Creating procedure sp_MSinsertcontents',0,1)
  1615. go
  1616. create procedure sp_MSinsertcontents
  1617.                 @tablenick int,
  1618.                 @rowguid uniqueidentifier,
  1619.                  @lineage varbinary(249),
  1620.                  @colv1 varbinary(2048)
  1621. AS
  1622.                 /*
  1623.                 ** permission check
  1624.                 */
  1625.                 declare @retcode    int
  1626.                 declare @objid        int
  1627.                 declare @owner        sysname
  1628.                 declare @artid        uniqueidentifier
  1629.                 declare @guidstr    nvarchar(32)    
  1630.                 declare @instrigger    sysname
  1631.                 
  1632.                 select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick
  1633.                 select @owner =user_name(uid) from sysobjects where id=@objid
  1634.  
  1635.                 exec @retcode=sp_MSguidtostr @artid, @guidstr out
  1636.                     if @retcode<>0 or @@ERROR<>0 return (1)
  1637.  
  1638.                 set @instrigger = @owner + '.ins_' + @guidstr
  1639.  
  1640.                 if trigger_nestlevel(object_id(@instrigger)) = 0
  1641.                 begin
  1642.                     raiserror(14126, 16, -1)
  1643.                     return (1) -- current user does not have insert permission to underlying table
  1644.                 end
  1645.             
  1646.                 insert into MSmerge_contents (tablenick, rowguid, generation, partchangegen, joinchangegen, lineage, colv1)
  1647.                     values (@tablenick, @rowguid, 0, 0, 0, @lineage, @colv1)
  1648.                 if @@error <> 0
  1649.                     begin
  1650.                     raiserror (20041, 16, -1)
  1651.                     return (1)
  1652.                     end            
  1653.  
  1654.                 delete from MSmerge_tombstone where rowguid = @rowguid and tablenick = @tablenick         
  1655.                 if @@error <> 0
  1656.                     begin
  1657.                     raiserror (20041, 16, -1)
  1658.                     return (1)
  1659.                     end    
  1660.  
  1661. go
  1662. exec dbo.sp_MS_marksystemobject sp_MSinsertcontents
  1663. go
  1664. grant exec on dbo.sp_MSinsertcontents to public
  1665.  
  1666. raiserror('Creating procedure sp_MSupdatecontents',0,1)
  1667. go
  1668. create procedure sp_MSupdatecontents
  1669.                  @tablenick int,
  1670.                  @rowguid uniqueidentifier,
  1671.                  @lineage varbinary(249),
  1672.                  @colv1 varbinary(2048),
  1673.                  @partchange int = null,
  1674.                  @joinchange int = null
  1675. AS
  1676.             /*
  1677.             ** permission check
  1678.             */
  1679.             declare @retcode    int
  1680.             declare @objid        int
  1681.             declare @owner        sysname
  1682.             declare @artid        uniqueidentifier
  1683.             declare @guidstr    nvarchar(32)    
  1684.             declare @updtrigger    sysname
  1685.             
  1686.             select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick
  1687.             select @owner =user_name(uid) from sysobjects where id=@objid
  1688.             
  1689.             exec @retcode=sp_MSguidtostr @artid, @guidstr out
  1690.                     if @retcode<>0 or @@ERROR<>0 return (1)
  1691.                     
  1692.                 set @updtrigger = @owner + '.upd_' + @guidstr
  1693.  
  1694.                 if trigger_nestlevel(object_id(@updtrigger)) = 0
  1695.                 begin
  1696.                     raiserror(14126, 16, -1)
  1697.                     return (1) -- current user does not 'update all' permission upon underlying table
  1698.                 end
  1699.             
  1700.             update MSmerge_contents set lineage = @lineage, generation = 0, colv1 = @colv1
  1701.                 where tablenick = @tablenick and rowguid = @rowguid
  1702.             if (@@rowcount = 0)
  1703.                 insert into MSmerge_contents (tablenick, rowguid, generation, joinchangegen, lineage, colv1)
  1704.                     values (@tablenick, @rowguid, 0, 1, @lineage, @colv1)
  1705.             if @@error <> 0
  1706.                 begin
  1707.                 raiserror (20041, 16, -1)
  1708.                 return (1)
  1709.                 end
  1710.             if @partchange = 1
  1711.                 begin
  1712.                 update MSmerge_contents set partchangegen = 0, joinchangegen = 0
  1713.                     where tablenick = @tablenick and rowguid = @rowguid
  1714.                 if @@error <> 0
  1715.                     begin
  1716.                     raiserror (20041, 16, -1)
  1717.                     return (1)
  1718.                     end
  1719.                 end
  1720.             else if @joinchange = 1
  1721.                 begin
  1722.                 update MSmerge_contents set joinchangegen = 0
  1723.                     where tablenick = @tablenick and rowguid = @rowguid
  1724.                 if @@error <> 0
  1725.                     begin
  1726.                     raiserror (20041, 16, -1)
  1727.                     return (1)
  1728.                     end
  1729.                 end 
  1730. go
  1731. exec dbo.sp_MS_marksystemobject sp_MSupdatecontents
  1732. go
  1733. grant exec on dbo.sp_MSupdatecontents to public
  1734.  
  1735. raiserror(15339, -1, -1, 'sp_MSdeletecontents')
  1736. go
  1737. create procedure sp_MSdeletecontents
  1738.                  @tablenick int,
  1739.                  @rowguid uniqueidentifier
  1740. AS
  1741.                 declare @nick int
  1742.                 declare @reason nvarchar(255)
  1743.                 declare @lineage varbinary(255)
  1744.  
  1745.                 /*
  1746.                 ** permission check
  1747.                 */
  1748.                 declare @retcode    int
  1749.                 declare @objid        int
  1750.                 declare @owner        sysname
  1751.                 declare @artid        uniqueidentifier
  1752.                 declare @guidstr    nvarchar(32)    
  1753.                 declare @deltrigger    sysname
  1754.                 
  1755.                 select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick
  1756.                 select @owner =user_name(uid) from sysobjects where id=@objid
  1757.                 
  1758.                 exec @retcode=sp_MSguidtostr @artid, @guidstr out
  1759.                     if @retcode<>0 or @@ERROR<>0 return (1)
  1760.  
  1761.                 set @deltrigger = @owner + '.del_' + @guidstr
  1762.  
  1763.                 if trigger_nestlevel(object_id(@deltrigger)) = 0
  1764.                     begin
  1765.                         raiserror(14126, 16, -1)
  1766.                         return (1) -- current user does not have 'delete' permission to underlying table
  1767.                     end
  1768.             
  1769.                 exec dbo.sp_MSgetreplnick @nickname = @nick out
  1770.                 if (@@error <> 0) or @nick IS NULL 
  1771.                     begin
  1772.                     RAISERROR (14055, 11, -1)
  1773.                     RETURN(1)
  1774.                     end                 
  1775.  
  1776.                 select @lineage = lineage from MSmerge_contents (UPDLOCK ROWLOCK index = 1) 
  1777.                     where tablenick = @tablenick and rowguid = @rowguid
  1778.                 exec master..xp_updatelineage @lineage output, @nick
  1779.                 select @reason = 'user delete'
  1780.     
  1781.                 insert into MSmerge_tombstone (rowguid, tablenick, type, lineage, generation, reason)
  1782.                     values (@rowguid, @tablenick, 1, @lineage, 0, @reason)
  1783.                 if @@error <> 0
  1784.                     begin
  1785.                     raiserror (20041, 16, -1)
  1786.                     return (1)
  1787.                     end
  1788.                 delete from MSmerge_contents where
  1789.                     tablenick = @tablenick and rowguid = @rowguid
  1790.                 if @@error <> 0
  1791.                     begin
  1792.                     raiserror (20041, 16, -1)
  1793.                     return (1)
  1794.                     end 
  1795. go
  1796. exec dbo.sp_MS_marksystemobject sp_MSdeletecontents
  1797. go        
  1798. grant exec on dbo.sp_MSdeletecontents to public
  1799.  
  1800.  
  1801. raiserror('Creating procedure sp_MSunmarkifneeded',0,1)
  1802. GO
  1803.  
  1804. CREATE PROCEDURE sp_MSunmarkifneeded(
  1805. @object                sysname,
  1806. @pubid                uniqueidentifier,
  1807. @pre_command         int = 1,
  1808. @publisher            sysname = NULL,
  1809. @publisher_db        sysname = NULL
  1810. )AS
  1811. declare @table_in_use    int
  1812. declare @retcode         int
  1813.  
  1814. select @table_in_use = 0
  1815. --if pre-creation_command is 'drop (1)' or 'truncate (3)', then disallow this deployment if there is already an article using that table.
  1816. --other commands, 'delete', and 'none' are fine', as long as the publication does not originate from same database.
  1817.  
  1818. if exists (select * from sysmergearticles where objid=object_id(@object) and pubid in
  1819.     (select pubid from sysmergepublications where LOWER(publisher)=LOWER(@publisher) and 
  1820.         publisher_db=@publisher_db and pubid<>@pubid))
  1821.     OR
  1822.     ((@pre_command=1 or @pre_command=3) and 
  1823.         EXISTS (select * from sysmergearticles where objid=object_id(@object) and pubid <> @pubid))
  1824. begin
  1825.     select @table_in_use = 1
  1826.     select @table_in_use
  1827.     return (0)
  1828. end
  1829. exec @retcode = sp_MSunmarkreplinfo @object
  1830. if @retcode <>0 or @@error<>0
  1831.     return (1)
  1832. select @table_in_use 
  1833. return (0)
  1834. GO
  1835. exec dbo.sp_MS_marksystemobject sp_MSunmarkifneeded
  1836. go        
  1837. grant exec on dbo.sp_MSunmarkifneeded to public
  1838. go
  1839.  
  1840. raiserror('Creating procedure sp_MSunmarkreplinfo',0,1)
  1841. GO
  1842.  
  1843. CREATE PROCEDURE sp_MSunmarkreplinfo(
  1844.     @object                sysname,            /* Name of the table, unqualitied */
  1845.     @owner                sysname = NULL,            /* Name of the owner, unqualified */
  1846.     @type                smallint = 0        /* default is to unmark, as name implies */
  1847. )AS
  1848. declare @merge_pub_object_bit int
  1849. declare @merge_pub_unmark_bit int
  1850. declare @id    int
  1851. declare @qualified_name            nvarchar(258)
  1852.  
  1853.  
  1854. if @owner is NULL or @owner=''
  1855.     select @owner = user_name(uid) from sysobjects where id = object_id(QUOTENAME(@object))
  1856. select @qualified_name = QUOTENAME(@owner) + '.' + QUOTENAME(@object) 
  1857.  
  1858.  
  1859. select @id = object_id(@qualified_name)
  1860.  
  1861. select @merge_pub_object_bit     = 128
  1862. select @merge_pub_unmark_bit = ~@merge_pub_object_bit
  1863.  
  1864. if exists (select name from sysobjects where id = @id) 
  1865.     begin
  1866.             if @type = 0    /* type = 0, unmark; else mark the bit */
  1867.         begin
  1868.             BEGIN TRANSACTION
  1869.                    exec dbo.sp_replupdateschema @qualified_name
  1870.                    update sysobjects set replinfo = replinfo & @merge_pub_unmark_bit where id = @id
  1871.             COMMIT TRANSACTION
  1872.         end
  1873.             else
  1874.         begin
  1875.             BEGIN TRANSACTION
  1876.                 exec dbo.sp_replupdateschema @qualified_name
  1877.                    update sysobjects set replinfo = replinfo | @merge_pub_object_bit where id = @id
  1878.                COMMIT TRANSACTION
  1879.         end
  1880.     end
  1881. GO
  1882. exec dbo.sp_MS_marksystemobject sp_MSunmarkreplinfo
  1883. go
  1884. grant execute on dbo.sp_MSunmarkreplinfo to public
  1885.  
  1886. raiserror('Creating procedure sp_MSaddanonymousreplica',0,1)
  1887. GO
  1888. CREATE PROCEDURE sp_MSaddanonymousreplica
  1889.     (@publication         sysname,
  1890.      @publisher            sysname,
  1891.      @publisherDB        sysname,
  1892.      @anonymous            int
  1893. )
  1894. as
  1895. declare @retcode                 int
  1896. declare @subscription_type         nvarchar(15)
  1897.  
  1898. if exists (select * from sysobjects where name='sysmergepublications')
  1899. begin
  1900.     IF EXISTS (select name from sysmergepublications where name=@publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisherDB)
  1901.         return (0)   -- replica exists. 
  1902.                 -- else call this SP to add this replica
  1903. end
  1904.  
  1905. if @anonymous = 1 select @subscription_type = 'anonymous'
  1906.     else select @subscription_type = 'local'
  1907.                 
  1908. exec @retcode = dbo.sp_addmergepullsubscription 
  1909.     @publication = @publication,
  1910.     @publisher = @publisher,
  1911.     @publisher_db=@publisherDB,
  1912.     @subscriber_type =@subscription_type
  1913.  
  1914. IF @retcode<>0 or @@ERROR<>0 return (1)
  1915. return (0)
  1916. GO
  1917. exec dbo.sp_MS_marksystemobject sp_MSaddanonymousreplica
  1918. go
  1919. grant execute on dbo.sp_MSaddanonymousreplica to public
  1920. go 
  1921.  
  1922. raiserror('Creating procedure sp_MSgetreplicainfo',0,1)
  1923. GO
  1924. CREATE PROCEDURE sp_MSgetreplicainfo
  1925.     (@publisher            sysname,
  1926.      @publisher_db        sysname,
  1927.      @publication         sysname,
  1928.      @datasource_type    int = 0,                 /* 0 = SQL Server, 1 = DSN, 2 = Jet */
  1929.      @server_name        sysname    = NULL,         /* Server Name */
  1930.      @db_name            sysname = NULL,         /* Database Name */
  1931.      @datasource_path    nvarchar(255) = NULL)    /* Datasource path - JET MDB file path etc */
  1932.      
  1933. as
  1934.     declare        @srvid                int
  1935.     declare        @retcode            int
  1936.     declare        @repid                 uniqueidentifier
  1937.     declare        @pubid                 uniqueidentifier
  1938.     declare        @schemaguid            uniqueidentifier
  1939.     declare      @nickname             int
  1940.     declare     @subscription_type int
  1941.     declare     @reptype             tinyint
  1942.     declare     @priority             real 
  1943.     declare     @schversion         int 
  1944.     declare     @status                int
  1945.     declare      @partnerid             uniqueidentifier
  1946.     declare     @sync_type             tinyint
  1947.     declare     @description         nvarchar(255)
  1948.  
  1949.     /*
  1950.     ** Parameter Check:  @publication.
  1951.     ** Make sure that the publication exists.
  1952.     */
  1953.     if (@publication is null)
  1954.         begin
  1955.         RAISERROR(14043, 16, -1, '@publication')
  1956.         return (1)
  1957.         end
  1958.  
  1959.     if (@server_name is NULL)
  1960.         SET @server_name = @@SERVERNAME
  1961.  
  1962.     if (@db_name is NULL)
  1963.         set @db_name = db_name()
  1964.         
  1965.     SELECT @srvid = srvid FROM master..sysservers WHERE UPPER(srvname) = UPPER(@server_name)
  1966.        IF @@ERROR <> 0
  1967.            BEGIN
  1968.             RAISERROR (14080, 16, -1)
  1969.              RETURN (1)
  1970.         END
  1971.  
  1972.     IF @srvid IS NULL
  1973.         BEGIN
  1974.             RAISERROR (14010, 16, -1)
  1975.             RETURN (1)
  1976.         END
  1977.  
  1978.     select @pubid = pubid from sysmergepublications 
  1979.         where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  1980.     if (@pubid is null)
  1981.         begin
  1982.             RAISERROR (20026, 16, -1, @publication)
  1983.             return (1)
  1984.         end
  1985.  
  1986.     if (@datasource_type = 0)
  1987.         begin
  1988.             SELECT @repid = subid, @priority = priority, @reptype = subscriber_type, 
  1989.                 @subscription_type = subscription_type , @status = status, 
  1990.                 @partnerid = partnerid, @sync_type = sync_type, @description = description FROM sysmergesubscriptions
  1991.                 WHERE srvid = @srvid and db_name = @db_name and pubid = @pubid
  1992.         END
  1993.     ELSE
  1994.         BEGIN
  1995.             SELECT @repid = subid, @priority = priority, @reptype = subscriber_type, 
  1996.                 @subscription_type = subscription_type , @status = status, 
  1997.                 @partnerid = partnerid, @sync_type = sync_type, @description = description FROM sysmergesubscriptions
  1998.                 WHERE srvid = @srvid and pubid = @pubid
  1999.         END
  2000.  
  2001.     if @repid is NULL
  2002.         begin
  2003.             RAISERROR(20021, 16, -1)
  2004.             return (1)
  2005.         end
  2006.     select @schversion = schemaversion, @schemaguid = schemaguid from MSmerge_replinfo where repid = @repid
  2007.     select @nickname = replnickname from MSmerge_replinfo where repid = @repid
  2008.     select @repid, @nickname, @reptype, @subscription_type, @priority, @schversion, @schemaguid,
  2009.         @status, @partnerid, @sync_type, @description
  2010.  
  2011.     return (0)
  2012. go
  2013. exec dbo.sp_MS_marksystemobject sp_MSgetreplicainfo
  2014. go
  2015. grant execute on dbo.sp_MSgetreplicainfo to public
  2016.  
  2017.  
  2018. raiserror('Creating procedure sp_MSadd_repl_job',0,1)
  2019. go
  2020.  
  2021. CREATE PROCEDURE sp_MSadd_repl_job
  2022.   @name                   nvarchar(200),
  2023.   @subsystem              nvarchar(60)  = 'TSQL',
  2024.   @server                 sysname  = NULL,
  2025.   @username               sysname  = NULL,
  2026.   @databasename           sysname  = NULL,
  2027.   @enabled                TINYINT      = 0,
  2028.   @freqtype               INT          = 2, -- 2 means OnDemand
  2029.   @freqinterval           INT          = 1,
  2030.   @freqsubtype            INT          = 1,
  2031.   @freqsubinterval        INT          = 1,
  2032.   @freqrelativeinterval   INT          = 1,
  2033.   @freqrecurrencefactor   INT          = 1,
  2034.   @activestartdate        INT          = 0,
  2035.   @activeenddate          INT          = 0,
  2036.   @activestarttimeofday   INT          = 0,
  2037.   @activeendtimeofday     INT          = 0,
  2038.   @nextrundate            INT          = 0,
  2039.   @nextruntime            INT          = 0,
  2040.   @runpriority            INT          = 0,
  2041.   @emailoperatorname      nvarchar(100) = NULL,
  2042.   @retryattempts          INT          = NULL,
  2043.   @retrydelay             INT          = 0,
  2044.   @command                nvarchar(4000)= NULL,
  2045.   @loghistcompletionlevel INT          = 2,
  2046.   @emailcompletionlevel   INT          = 0,
  2047.   @description            nvarchar(255) = NULL,
  2048.   @tagadditionalinfo      nvarchar(96)  = NULL,
  2049.   @tagobjectid            INT          = NULL,
  2050.   @tagobjecttype          INT          = NULL,
  2051.   @cmdexecsuccesscode     INT          = 0,
  2052.   @category_name          sysname = NULL, -- New for 7.0
  2053.   @failure_detection      BIT            = 0,
  2054.   @agent_id                  INT            = NULL,
  2055.   @job_id BINARY(16) = NULL OUTPUT
  2056. AS
  2057. BEGIN
  2058.   DECLARE    @retval INT
  2059.   declare    @step_id int
  2060.   declare    @step_name nvarchar(100)
  2061.   declare    @step_command nvarchar(1024)
  2062.   declare    @on_fail_action tinyint
  2063.   declare     @on_success_action tinyint
  2064.   declare    @schedule_name nvarchar(100)
  2065.   declare    @comments nvarchar(100)
  2066.  
  2067.   SET NOCOUNT ON
  2068.  
  2069.   SELECT @retval = 1 -- 0 means success, 1 means failure
  2070.   set @step_id = 1
  2071.   set @on_fail_action = 2    -- Return failure
  2072.   set @on_success_action = 1    -- Return success
  2073.   set @step_command = NULL
  2074.  
  2075.   /*
  2076.   ** Set default retries to every minute for 10 minutes.
  2077.   **
  2078.   */
  2079.   if @retryattempts = NULL and @retrydelay = 0
  2080.   begin
  2081.      select @retryattempts = 10
  2082.      select @retrydelay = 1
  2083.   end
  2084.  
  2085.   BEGIN TRANSACTION
  2086.  
  2087.     -- Drop the job if it already exists
  2088.     IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @name)
  2089.     begin
  2090.         exec @retval = msdb.dbo.sp_delete_job @job_name=@name
  2091.         if @@ERROR<>0 or @retval<>0
  2092.             goto UNDO
  2093.     end
  2094.  
  2095.     -- Add the job
  2096.     EXECUTE @retval = msdb.dbo.sp_add_job
  2097.       @job_name                   = @name,
  2098.       @enabled                    = @enabled,
  2099.       @start_step_id              = 1,
  2100.       @description                = @description,
  2101.       @category_name              = @category_name,
  2102.       @notify_level_eventlog      = @loghistcompletionlevel,
  2103.       @notify_level_email         = @emailcompletionlevel,
  2104.       @notify_email_operator_name = @emailoperatorname,
  2105.       @job_id = @job_id OUTPUT
  2106.  
  2107.     IF (@retval <> 0)
  2108.     BEGIN
  2109.         GOTO UNDO
  2110.     END
  2111.  
  2112.     -- Add startup message step
  2113.     if @failure_detection = 1
  2114.     begin
  2115.  
  2116.         select @step_name = formatmessage(20528)
  2117.         select @comments = formatmessage(20529)
  2118.  
  2119.         -- Construct command based on subsystem type
  2120.         select @step_command =
  2121.             case UPPER(@subsystem) 
  2122.                 WHEN 'SNAPSHOT' THEN
  2123.                 N'sp_MSadd_snapshot_history @perfmon_increment = 0,  @agent_id = ' + 
  2124.                     convert (nvarchar(10), @agent_id) + N', @runstatus = 1,  
  2125.                     @comments = ''' + @comments + ''''
  2126.                 WHEN 'LOGREADER' THEN
  2127.                 N'sp_MSadd_logreader_history @perfmon_increment = 0, @agent_id = ' + 
  2128.                     convert (nvarchar(10), @agent_id) + N', @runstatus = 1, 
  2129.                     @comments = ''' + @comments + ''''
  2130.                 WHEN 'DISTRIBUTION' THEN
  2131.                 N'sp_MSadd_distribution_history @perfmon_increment = 0, @agent_id = ' + 
  2132.                     convert (nvarchar(10), @agent_id) + N', @runstatus = 1,  
  2133.                     @comments = ''' + @comments + ''''
  2134.                 WHEN 'MERGE' THEN
  2135.                 N'sp_MSadd_merge_history @perfmon_increment = 0, @agent_id = ' + 
  2136.                     convert (nvarchar(10),@agent_id) + N', @runstatus = 1,  
  2137.                     @comments = ''' + @comments + ''''
  2138.             end
  2139.     
  2140.         -- Add the job step
  2141.         EXECUTE @retval = msdb.dbo.sp_add_jobstep
  2142.           @job_id                = @job_id,
  2143.           @step_id               = @step_id,
  2144.           @step_name             = @step_name,
  2145.           @command               = @step_command,
  2146.           @cmdexec_success_code  = @cmdexecsuccesscode,
  2147.           @on_success_action     = 3,    -- Goto next step
  2148.           @on_fail_action         = 3,    -- Goto next step
  2149.           @server                = @server,
  2150.           @database_name         = @databasename,
  2151.           @database_user_name    = @username,
  2152.           @os_run_priority       = @runpriority
  2153.  
  2154.         IF (@retval <> 0)
  2155.         BEGIN
  2156.             GOTO UNDO
  2157.         END
  2158.  
  2159.         set @step_id = @step_id + 1
  2160.         set @on_fail_action = 3            -- Goto next step
  2161.     end
  2162.  
  2163.     -- Add the job step
  2164.      select @step_name = formatmessage(20530)
  2165.     EXECUTE @retval = msdb.dbo.sp_add_jobstep
  2166.       @job_id                = @job_id,
  2167.       @step_id               = @step_id,
  2168.       @step_name             = @step_name,
  2169.       @subsystem             = @subsystem,
  2170.       @command               = @command,
  2171.       @cmdexec_success_code  = @cmdexecsuccesscode,
  2172.       @on_success_action     = @on_success_action,
  2173.       @on_fail_action         = @on_fail_action,
  2174.       @server                = @server,
  2175.       @database_name         = @databasename,
  2176.       @database_user_name    = @username,
  2177.       @retry_attempts        = @retryattempts,
  2178.       @retry_interval        = @retrydelay,
  2179.       @os_run_priority       = @runpriority
  2180.  
  2181.     IF (@retval <> 0)
  2182.     BEGIN
  2183.         GOTO UNDO
  2184.     END
  2185.  
  2186.     -- Add failure message step
  2187.     if @failure_detection = 1
  2188.     begin
  2189.  
  2190.         set @step_id = @step_id + 1
  2191.  
  2192.          select @step_name = formatmessage(20531)
  2193.  
  2194.         -- Construct command
  2195.         select @step_command = N'sp_MSdetect_nonlogged_shutdown @subsystem = ''' + @subsystem +     N''', @agent_id = ' + convert (nvarchar(10),    @agent_id) 
  2196.  
  2197.         -- Add the job step
  2198.         EXECUTE @retval = msdb.dbo.sp_add_jobstep
  2199.           @job_id                = @job_id,
  2200.           @step_id               = @step_id,
  2201.           @step_name             = @step_name,
  2202.           @command               = @step_command,
  2203.           @cmdexec_success_code  = @cmdexecsuccesscode,
  2204.           @on_success_action     = 2,                    -- Always quit with failure
  2205.           @server                = @server,
  2206.           @database_name         = @databasename,
  2207.           @database_user_name    = @username,
  2208.           @os_run_priority       = @runpriority
  2209.  
  2210.         IF (@retval <> 0)
  2211.         BEGIN
  2212.             GOTO UNDO
  2213.         END
  2214.     end
  2215.  
  2216.     -- Add the job schedule
  2217.     IF (@activestartdate = 0)
  2218.       SELECT @activestartdate = NULL
  2219.     IF (@activeenddate = 0)
  2220.       SELECT @activeenddate = NULL
  2221.     
  2222.     -- But if @activeenddate is NOT NULL, then @activestartdate cannot be allowed to be NULL either.  Set it to today's date converted to the int format used yyyymmdd
  2223.  
  2224.     IF (@activeenddate IS NOT NULL AND @activestartdate IS NULL)
  2225.     SELECT @activestartdate=DATEPART(YYYY,getdate()) * 10000 + DATEPART(MM,getdate()) * 100 + DATEPART(DD,getdate())
  2226.  
  2227.     -- But never let startdate be > end date
  2228.     IF (@activestartdate > @activeenddate)
  2229.     SELECT @activestartdate=@activeenddate
  2230.  
  2231.     IF (@activestarttimeofday = 0)
  2232.       SELECT @activestarttimeofday = NULL
  2233.     IF (@activeendtimeofday = 0)
  2234.       SELECT @activeendtimeofday = NULL
  2235.     IF (@freqtype <> 0x2) -- OnDemand tasks simply have no schedule in 7.0
  2236.     BEGIN
  2237.       select @schedule_name = formatmessage(20532)
  2238.  
  2239.       EXECUTE @retval = msdb.dbo.sp_add_jobschedule
  2240.         @job_id                 = @job_id,
  2241.         @name                   = @schedule_name,
  2242.         @enabled                = 1,
  2243.         @freq_type              = @freqtype,
  2244.         @freq_interval          = @freqinterval,
  2245.         @freq_subday_type       = @freqsubtype,
  2246.         @freq_subday_interval   = @freqsubinterval,
  2247.         @freq_relative_interval = @freqrelativeinterval,
  2248.         @freq_recurrence_factor = @freqrecurrencefactor,
  2249.         @active_start_date      = @activestartdate,
  2250.         @active_end_date        = @activeenddate,
  2251.         @active_start_time      = @activestarttimeofday,
  2252.         @active_end_time        = @activeendtimeofday
  2253.  
  2254.       IF (@retval <> 0)
  2255.       BEGIN
  2256.         GOTO UNDO
  2257.       END
  2258.     END
  2259.  
  2260.     -- And finally, add the job server
  2261.     EXECUTE @retval = msdb.dbo.sp_add_jobserver @job_id = @job_id, @server_name  = '(local)'
  2262.  
  2263.     IF (@retval <> 0)
  2264.     BEGIN
  2265.       GOTO UNDO
  2266.     END
  2267.  
  2268.   COMMIT TRANSACTION
  2269.  
  2270.   -- If this is an autostart LogReader or Distribution or Merge job, add the [new] '-Continuous' paramter to the command
  2271.   IF (@freqtype = 0x40) AND ((UPPER(@subsystem) = 'LOGREADER') OR (UPPER(@subsystem) = 'DISTRIBUTION') OR (UPPER(@subsystem) = 'MERGE'))
  2272.   BEGIN
  2273.     UPDATE msdb.dbo.sysjobsteps
  2274.     SET command = command + ' -Continuous'
  2275.     WHERE (job_id = @job_id)
  2276.       AND ((@failure_detection = 0 and step_id = 1) or (@failure_detection = 1 and step_id = 2))
  2277.   END  
  2278.  
  2279.   -- If this is an autostart job, start it now (for backwards compatibility with 6.x SQLExecutive behaviour)
  2280.   IF (@freqtype = 0x40)
  2281.     EXECUTE msdb.dbo.sp_start_job @job_id = @job_id, @error_flag = 0
  2282.  
  2283.   RETURN(0)
  2284.  
  2285. UNDO:
  2286.     if @@TRANCOUNT = 1
  2287.         ROLLBACK TRAN
  2288.     else
  2289.         COMMIT TRAN
  2290.     return(1)
  2291.  
  2292. END
  2293. go
  2294.  
  2295. raiserror('Creating procedure sp_MScheck_subscription', 0,1)
  2296. go
  2297.  
  2298. CREATE PROCEDURE sp_MScheck_subscription (
  2299. @publication    sysname,  --     1 Tran, 2 Merge
  2300. @pub_type        int
  2301. )AS
  2302. declare @merge_pubid    uniqueidentifier
  2303. declare @tran_pubid        int
  2304.  
  2305. if @pub_type = 2
  2306. BEGIN
  2307.     if not exists (select * from sysobjects where name = 'sysmergepublications')
  2308.         begin
  2309.             raiserror(20054, 16, -1)
  2310.             return (1)
  2311.         end
  2312.     select @merge_pubid = pubid from sysmergepublications where name=@publication and publisher=@@SERVERNAME and publisher_db=db_name()
  2313.     if @merge_pubid is NULL
  2314.         begin
  2315.             raiserror(20026, 16, -1, @publication)
  2316.             return (1)
  2317.         end
  2318.     if EXISTS (select * from sysmergesubscriptions where pubid=@merge_pubid and subid<>pubid)
  2319.         select 1
  2320.     else 
  2321.         select 0
  2322. END
  2323. else    -- if not merge, it has to be tran level. For other level, a generic error will be returned
  2324. BEGIN
  2325.     if not exists (select * from sysobjects where name='syspublications')
  2326.         begin
  2327.             raiserror(20054, 16, -1)
  2328.             return (1)
  2329.         end
  2330.     select @tran_pubid = pubid from syspublications where name=@publication
  2331.     if @tran_pubid is NULL 
  2332.         begin
  2333.             raiserror(20026, 16, -1, @publication)
  2334.             return (1)
  2335.         end
  2336.     if EXISTS (select * from syssubscriptions where (srvid <> -1) and artid in 
  2337.                        (select artid from sysarticles where pubid=@tran_pubid))
  2338.           select 1
  2339.     else
  2340.            select 0
  2341. END
  2342. GO
  2343.  
  2344. exec dbo.sp_MS_marksystemobject sp_MScheck_subscription
  2345. go
  2346. grant execute on dbo.sp_MScheck_subscription to public
  2347. go
  2348.  
  2349.  
  2350. raiserror('Creating procedure sp_replicationoption', 0,1)
  2351. go
  2352.  
  2353. CREATE PROCEDURE sp_replicationoption (
  2354. @optname        sysname,
  2355. @value            nvarchar(5),
  2356. @security_mode    int = 0,
  2357. @login            sysname = 'sa',
  2358. @password        sysname = NULL,
  2359. @reserved       nvarchar(20) = NULL
  2360. )
  2361. AS
  2362.     DECLARE @optbit bit
  2363.     DECLARE @osql_cmd1 nvarchar (255)
  2364.     DECLARE @osql_cmd_full nvarchar (255)
  2365.     DECLARE @osql_for_nt int
  2366.  
  2367.     DECLARE @install_path nvarchar (255)
  2368.  
  2369.     DECLARE @retcode int
  2370.     DECLARE @undo_install nvarchar(20)
  2371.     DECLARE @no_scripts nvarchar(10)
  2372.     DECLARE @platform_nt binary
  2373.     
  2374.     SELECT @platform_nt = 0x1
  2375.  
  2376.     if    is_srvrolemember('sysadmin') <> 1
  2377.         BEGIN
  2378.             RAISERROR (15232, 14, -1)
  2379.             RETURN (1)
  2380.         END
  2381.     
  2382.     SELECT @no_scripts = 'no_scripts'
  2383.  
  2384.     SELECT @undo_install = 'undo_install'
  2385.  
  2386.     IF db_name() <> 'master'
  2387.     BEGIN
  2388.         RAISERROR(5001, 16,-1)
  2389.         GOTO FAILURE
  2390.     END
  2391.  
  2392.     IF LOWER(@optname) NOT IN ('transactional','merge')
  2393.     BEGIN
  2394.         RAISERROR(21014, 16, -1)
  2395.         GOTO FAILURE
  2396.     END
  2397.     IF LOWER(@value) NOT IN ('true','false')
  2398.     BEGIN
  2399.         RAISERROR(14137,16,-1)
  2400.         GOTO FAILURE
  2401.     END
  2402.     
  2403.     IF LOWER(@value) = 'true'
  2404.         SELECT @optbit = 1
  2405.     ELSE
  2406.         SELECT @optbit = 0
  2407.  
  2408.     /*
  2409.     ** Check if the option is set as required already
  2410.     */
  2411.     IF @reserved <> @undo_install AND EXISTS (SELECT * FROM MSreplication_options
  2412.         WHERE    optname  = @optname
  2413.         AND        value = @optbit)
  2414.     BEGIN
  2415.         IF LOWER(@value) = 'true'
  2416.             RAISERROR (21015, 10, -1, @optname)        
  2417.         ELSE
  2418.             RAISERROR (21016, 10, -1, @optname)
  2419.         GOTO FAILURE
  2420.     END
  2421.  
  2422.     /* Install replication */
  2423.     IF @optbit = 1
  2424.     BEGIN
  2425.  
  2426.         IF LOWER(@reserved) = @no_scripts
  2427.             GOTO NO_SCRIPTS
  2428.  
  2429.         -- Set the flag for platform
  2430.         IF (( platform() & @platform_nt = @platform_nt ))
  2431.             SELECT @osql_for_nt = 1
  2432.         ELSE
  2433.             SELECT @osql_for_nt = 0
  2434.  
  2435.         /* 
  2436.         ** Get installation path
  2437.         */
  2438.         EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  2439.                   'SOFTWARE\Microsoft\MSSQLServer\Setup',
  2440.                   'SQLPath',
  2441.                 @param = @install_path OUTPUT
  2442.         IF @@ERROR<> 0 OR @retcode <> 0 or @install_path is NULL or @install_path=''
  2443.             BEGIN
  2444.                 GOTO FAILURE       
  2445.             END
  2446.  
  2447.         /* 
  2448.         ** Install replcom.sql and repltran.sql
  2449.         */
  2450.         IF @security_mode = 1
  2451.             SELECT @osql_cmd1 = '"' + @install_path + '\binn\osql" -E ' 
  2452.         ELSE
  2453.             -- cannot specify -S w/ -E for local execution, SID does not map due to nofix bug
  2454.             SELECT @osql_cmd1 = '"' + @install_path + '\binn\osql" -U' + @login + ' -P' + 
  2455.                 isnull(@password,'') + ' -S' + @@SERVERNAME + ' '
  2456.  
  2457.         select @osql_cmd1 = @osql_cmd1 + '-l30 -t30 '
  2458.  
  2459.         -- Install replcom.sql 
  2460.         -- bug24982 Only apply replcom.sql if it was not applied before.
  2461.         -- '-b' option will make osql stop at errors and return error code
  2462.         -- We must use this option.
  2463.         IF NOT EXISTS (SELECT * FROM MSreplication_options
  2464.             WHERE value = 1)
  2465.         BEGIN
  2466.             -- Initialize the Command
  2467.             IF (@osql_for_nt = 1)
  2468.                 SELECT @osql_cmd_full = '" '
  2469.             ELSE
  2470.                 SELECT @osql_cmd_full = ' '
  2471.  
  2472.             SELECT @osql_cmd_full = @osql_cmd_full +
  2473.                 @osql_cmd1 + 
  2474.                 ' -dmaster' +  ' -b ' +
  2475.                 ' -i' + '"' + @install_path + '\install\replcom.sql"' + 
  2476.                 ' -o' + '"' + @install_path + '\install\replcom.out"' 
  2477.  
  2478.             IF (@osql_for_nt = 1)
  2479.                 SELECT @osql_cmd_full = @osql_cmd_full + ' "'
  2480.  
  2481.             EXEC @retcode = master..xp_cmdshell @osql_cmd_full
  2482.             IF @@ERROR<> 0 OR @retcode <> 0
  2483.             BEGIN
  2484.                 RAISERROR (14113, 16, -1, @osql_cmd_full, 'replcom.out')
  2485.                 GOTO UNDO_INSTALL     
  2486.             END
  2487.         END
  2488.  
  2489.         IF LOWER(@optname) = 'transactional'
  2490.         BEGIN
  2491.             -- Install repltran.sql
  2492.             IF (@osql_for_nt = 1)
  2493.                 SELECT @osql_cmd_full = '" '
  2494.             ELSE
  2495.                 SELECT @osql_cmd_full = ' '
  2496.  
  2497.             SELECT @osql_cmd_full = @osql_cmd_full +
  2498.                 @osql_cmd1 + 
  2499.                 ' -dmaster' +  ' -b ' +
  2500.                 ' -i' + '"' + @install_path + '\install\repltran.sql"' + 
  2501.                 ' -o' + '"' + @install_path + '\install\repltran.out"' 
  2502.  
  2503.             IF (@osql_for_nt = 1)
  2504.                 SELECT @osql_cmd_full = @osql_cmd_full + ' "'
  2505.  
  2506.             EXEC @retcode = master..xp_cmdshell @osql_cmd_full
  2507.             IF @@ERROR<> 0 OR @retcode <> 0
  2508.             BEGIN
  2509.                 RAISERROR (14113, 16, -1, @osql_cmd_full, 'repltran.out')
  2510.                 GOTO UNDO_INSTALL     
  2511.             END
  2512.  
  2513.         END
  2514.  
  2515.         IF LOWER(@optname) = 'merge'
  2516.         BEGIN
  2517.             -- Install replmerg.sql 
  2518.             IF (@osql_for_nt = 1)
  2519.                 SELECT @osql_cmd_full = '" '
  2520.             ELSE
  2521.                 SELECT @osql_cmd_full = ' '
  2522.  
  2523.             SELECT @osql_cmd_full = @osql_cmd_full +
  2524.                 @osql_cmd1 + 
  2525.                 ' -dmaster' + ' -b ' +
  2526.                 ' -i' + '"' + @install_path + '\install\replmerg.sql"' + 
  2527.                 ' -o' + '"' + @install_path + '\install\replmerg.out"' 
  2528.             
  2529.             IF (@osql_for_nt = 1)
  2530.                 SELECT @osql_cmd_full = @osql_cmd_full + ' "'
  2531.  
  2532.             EXEC @retcode = master..xp_cmdshell @osql_cmd_full 
  2533.             
  2534.             IF  @@ERROR<> 0 OR @retcode <> 0
  2535.             BEGIN
  2536.                 RAISERROR (14113, 16, -1, @osql_cmd_full, 'replmerg.out')
  2537.                 GOTO UNDO_INSTALL     
  2538.             END
  2539.         END
  2540.  
  2541. NO_SCRIPTS:
  2542.  
  2543.         UPDATE MSreplication_options SET value = @optbit
  2544.             WHERE optname = @optname
  2545.         IF @@ERROR <> 0 
  2546.         BEGIN
  2547.             GOTO UNDO_INSTALL    
  2548.         END
  2549.  
  2550.     END
  2551.     /* Uninstall replication */
  2552.     ELSE
  2553.     BEGIN
  2554.  
  2555.         /* 
  2556.         ** Make sure no distributor installed before dropping 
  2557.         ** replication stored procedures
  2558.         */
  2559.         IF EXISTS (SELECT * FROM master..sysservers
  2560.               WHERE  srvstatus & 8 <> 0)
  2561.         BEGIN
  2562.             RAISERROR (21021, 16, -1)
  2563.             RETURN(1)
  2564.         END
  2565.  
  2566.         UPDATE MSreplication_options SET value = @optbit
  2567.             WHERE optname = @optname
  2568.         IF @@ERROR <> 0 
  2569.         BEGIN
  2570.             GOTO FAILURE
  2571.         END
  2572.  
  2573.         /* 
  2574.         *********** Do not drop replication stored procs anymore.
  2575.  
  2576.         IF LOWER(@optname) = 'transactional'
  2577.         BEGIN
  2578.             if exists (select * from sysobjects
  2579.                 where type = 'P '
  2580.                         and name = 'sp_MSdrop_repltran')
  2581.             begin
  2582.                 exec @retcode = dbo.sp_MSdrop_repltran
  2583.                 if @@ERROR = 0 and @retcode = 0
  2584.                     drop procedure sp_MSdrop_repltran
  2585.             end
  2586.         END
  2587.  
  2588.         IF LOWER(@optname) = 'merge'
  2589.         BEGIN
  2590.             if exists (select * from sysobjects
  2591.                 where type = 'P '
  2592.                         and name = 'sp_MSdrop_replmerg')
  2593.             begin
  2594.                 exec @retcode = dbo.sp_MSdrop_replmerg
  2595.                 if @@ERROR = 0 and @retcode = 0
  2596.                     drop procedure sp_MSdrop_replmerg
  2597.             end
  2598.         END
  2599.  
  2600.         IF NOT EXISTS (SELECT * FROM MSreplication_options
  2601.             WHERE value = 1)
  2602.         BEGIN
  2603.             if exists (select * from sysobjects
  2604.                 where type = 'P '
  2605.                         and name = 'sp_MSdrop_replcom')
  2606.             begin
  2607.                 exec @retcode = dbo.sp_MSdrop_replcom
  2608.                 if @@ERROR = 0 and @retcode = 0
  2609.                     drop procedure sp_MSdrop_replcom
  2610.             end
  2611.         END
  2612.  
  2613.         */
  2614.     END
  2615.  
  2616.     RETURN(0)
  2617.  
  2618. UNDO_INSTALL:
  2619.     /* This is needed to drop the stored procedures that were created. */
  2620.     EXEC dbo.sp_replicationoption @optname =  @optname, 
  2621.         @value = 'false', @reserved = @undo_install
  2622.  
  2623. FAILURE:
  2624.     RETURN(1)
  2625. GO
  2626. exec dbo.sp_MS_marksystemobject sp_replicationoption
  2627. go
  2628. grant execute on dbo.sp_replicationoption to public
  2629.     
  2630.  
  2631. raiserror('Creating procedure sp_helpreplicationoption', 0,1)
  2632. go
  2633.  
  2634. CREATE PROCEDURE sp_helpreplicationoption (
  2635. @optname        sysname = NULL
  2636. )
  2637. AS
  2638.     DECLARE @optbit bit
  2639.     DECLARE @retcode int
  2640.  
  2641.  
  2642.     IF @optname IS NOT NULL AND LOWER(@optname) NOT IN ('transactional','merge')
  2643.     BEGIN
  2644.         RAISERROR(21014, 16, -1)
  2645.         GOTO FAILURE
  2646.     END
  2647.     
  2648.     SELECT optname, value, major_version, minor_version, revision 
  2649.         FROM MSreplication_options
  2650.         WHERE
  2651.             optname = @optname OR
  2652.             @optname = NULL
  2653.  
  2654.     RETURN(0)
  2655.  
  2656. FAILURE:
  2657.     RETURN(1)
  2658. GO
  2659. exec dbo.sp_MS_marksystemobject sp_helpreplicationoption
  2660. go
  2661. grant execute on dbo.sp_helpreplicationoption to public
  2662.  
  2663. raiserror('Creating procedure sp_MSgetreplnick', 0,1)
  2664. GO
  2665.  
  2666. create procedure sp_MSgetreplnick (
  2667.     @server        sysname = NULL,
  2668.     @db_name    sysname = NULL,
  2669.     @pubid        uniqueidentifier  = NULL,
  2670.     @nickname    int output
  2671.     )
  2672. as
  2673.     declare @srvid             int
  2674.     
  2675.     if @db_name IS NULL
  2676.         select @db_name = db_name()
  2677.  
  2678.     /* Use 0 if the Server name is not passed in since it would be the local server */
  2679.     if @server IS NULL
  2680.         select @srvid = 0
  2681.     else            
  2682.         select @srvid = max(srvid) from master..sysservers where UPPER(srvname) = UPPER(@server)
  2683.  
  2684.     if (@pubid IS NOT NULL)
  2685.         begin
  2686.             select @nickname = max(replnickname) from MSmerge_replinfo 
  2687.                 where repid in (select subid from sysmergesubscriptions
  2688.                     where srvid = @srvid and db_name = @db_name and pubid = @pubid)
  2689.         end
  2690.     else
  2691.         begin
  2692.             select @nickname = max(replnickname) from MSmerge_replinfo 
  2693.                 where repid in (select subid from sysmergesubscriptions
  2694.                         where srvid = @srvid and db_name = @db_name)
  2695.         end
  2696. go
  2697.  
  2698. exec dbo.sp_MS_marksystemobject sp_MSgetreplnick
  2699. go
  2700. grant execute on dbo.sp_MSgetreplnick to public
  2701.  
  2702. raiserror('Creating procedure sp_MSreplcheck_publish', 0,1)
  2703. go
  2704.  
  2705. CREATE PROCEDURE sp_MSreplcheck_publish 
  2706. AS
  2707.     if    is_srvrolemember('sysadmin') <> 1  and
  2708.         is_member ('db_owner') <> 1
  2709.         BEGIN
  2710.             RAISERROR (21050, 14, -1)
  2711.             RETURN (1)
  2712.         END
  2713. GO
  2714.  
  2715.  
  2716. raiserror('Creating procedure sp_MSlocktable', 0,1)
  2717. go
  2718. CREATE PROCEDURE sp_MSlocktable
  2719. @ownername        sysname,
  2720. @tablename        sysname
  2721. AS
  2722.     declare @ispublisher            bit
  2723.     declare @retcode            int
  2724.     declare @procname            sysname
  2725.     declare @objid                 int
  2726.     declare @qualified_name        nvarchar(255)
  2727.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@tablename)
  2728.     select @objid = object_id(@qualified_name)
  2729.     if @objid is NULL
  2730.         begin
  2731.             select @ispublisher = 0
  2732.             select @qualified_name = QUOTENAME(@tablename)
  2733.             select @objid = object_id(@qualified_name)
  2734.         end
  2735.     else
  2736.         select @ispublisher = 1
  2737.     
  2738.     exec dbo.sp_MSreplcheck_connection @objid = @objid 
  2739.     
  2740.     select @procname = select_proc from sysmergearticles where objid = @objid and select_proc is not NULL
  2741.     exec @retcode = @procname @type = 7
  2742.  
  2743. --  exec ('select count(*) from ' + @ownername + '.' + @tablename + ' (tablock holdlock) where 1 = 2')
  2744. go
  2745. exec dbo.sp_MS_marksystemobject sp_MSlocktable
  2746. go
  2747. grant execute on dbo.sp_MSlocktable to public
  2748. go
  2749.  
  2750. raiserror('Creating procedure sp_MSenumcolumns', 0,1)
  2751. go
  2752. CREATE PROCEDURE sp_MSenumcolumns
  2753.     @pubid uniqueidentifier,
  2754.     @artid uniqueidentifier
  2755. AS
  2756.     declare @retcode            int
  2757.     declare @procname            sysname
  2758.  
  2759.     select @procname = select_proc from sysmergearticles where pubid = @pubid and artid = @artid
  2760.     exec @retcode = @procname @type =6
  2761.  
  2762. go
  2763. exec dbo.sp_MS_marksystemobject sp_MSenumcolumns
  2764. go
  2765. grant execute on dbo.sp_MSenumcolumns to public
  2766. go
  2767.  
  2768. /*
  2769. ** Get pubid through connection_ID and check permission of this publication
  2770. */
  2771.  
  2772. raiserror('Creating procedure sp_MSsetaccesslist', 0,1)
  2773. go
  2774. CREATE PROCEDURE sp_MSsetaccesslist
  2775. @publication     sysname,
  2776. @publisher         sysname,
  2777. @publisher_db    sysname
  2778. AS
  2779. declare @pubid uniqueidentifier
  2780.         select @pubid = pubid from sysmergepublications where 
  2781.                     name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  2782.         exec dbo.sp_MSreplcheck_connection
  2783.             @publication = @publication,
  2784.             @pubid = @pubid,
  2785.             @is_init = 1
  2786. go
  2787. exec dbo.sp_MS_marksystemobject sp_MSsetaccesslist
  2788. go
  2789. grant execute on dbo.sp_MSsetaccesslist to public
  2790. go
  2791.             
  2792. raiserror('Creating procedure sp_MSreplcheck_connection', 0,1)
  2793. go
  2794.  
  2795. CREATE PROCEDURE sp_MSreplcheck_connection
  2796. @publication sysname = NULL,
  2797. @artid uniqueidentifier = NULL,
  2798. @repid uniqueidentifier = NULL,
  2799. @pubid uniqueidentifier = NULL,
  2800. @objid int                = NULL,
  2801. @tablenick int = NULL,
  2802. @is_init bit = 0
  2803. AS
  2804.     -- sysadmin or db_owner have access
  2805.     if is_srvrolemember('sysadmin') = 1 or 
  2806.         is_member('db_owner') = 1
  2807.         return 0
  2808.  
  2809.     declare @retcode int
  2810.     declare @cached_id uniqueidentifier
  2811.  
  2812.     -- Need login_time to uniquely identify a connection.
  2813.     declare @login_time datetime
  2814.     select @login_time = login_time from master..sysprocesses where spid = @@spid
  2815.  
  2816.     select @cached_id = pubid from tempdb.dbo.MSpublisher_access where 
  2817.         spid = @@spid and
  2818.         login_time = @login_time
  2819.  
  2820.     -- If spid with publication in the cache, return success.
  2821.     if @cached_id is null
  2822.     begin
  2823.         -- This stored procedure might be called by common sprocs at
  2824.         -- both the publisher and the subscriber by the merge agent
  2825.         -- The merge agent will call this sp with @is_init = 1 before
  2826.         -- any other calls to the publisher. All the other calls will
  2827.         -- set @is_init to 0.
  2828.         if @is_init = 0
  2829.         begin
  2830.             RAISERROR (14126, 11, -1)
  2831.             return (1)
  2832.         end
  2833.         else
  2834.         begin
  2835.             exec @retcode = dbo.sp_MSreplcheck_pull @publication = @publication,
  2836.                 @pubid = @pubid
  2837.             if @retcode <> 0 or @@error <> 0
  2838.                 return (1)
  2839.         end
  2840.     end
  2841.     else
  2842.     begin
  2843.         if @pubid is not null
  2844.         begin
  2845.             if @pubid <> @cached_id
  2846.             begin
  2847.                 RAISERROR (14126, 11, -1)
  2848.                 return (1)
  2849.             end
  2850.  
  2851.         end
  2852.         else if @tablenick is not null
  2853.         begin
  2854.             if not exists (select * from sysmergearticles where pubid = @cached_id and 
  2855.                 nickname = @tablenick)
  2856.             begin
  2857.                 RAISERROR (14126, 11, -1)
  2858.                 return (1)
  2859.             end
  2860.         end
  2861.         else if @artid is not null
  2862.         begin
  2863.             if not exists (select * from sysmergearticles where pubid = @cached_id and 
  2864.                 artid = @artid)
  2865.             begin
  2866.                 RAISERROR (14126, 11, -1)
  2867.                 return (1)
  2868.             end
  2869.         end
  2870.         else if @objid is not null
  2871.         begin
  2872.             if not exists (select * from sysmergearticles where pubid = @cached_id and 
  2873.                 objid=@objid)
  2874.             begin
  2875.                 RAISERROR (14126, 11, -1)
  2876.                 return (1)
  2877.             end
  2878.         end
  2879.         
  2880.         else if @publication is not null
  2881.         begin
  2882.             if not exists (select * from sysmergepublications where pubid = @cached_id and 
  2883.                 name = @publication)
  2884.             begin
  2885.                 RAISERROR (14126, 11, -1)
  2886.                 return (1)
  2887.             end
  2888.         end
  2889.         else if @repid is not null
  2890.         begin
  2891.             if not exists (select * from sysmergesubscriptions where pubid = @cached_id and 
  2892.                 subid = @repid)
  2893.             begin
  2894.                 RAISERROR (14126, 11, -1)
  2895.                 return (1)
  2896.             end
  2897.         end
  2898.     end
  2899. GO
  2900. exec dbo.sp_MS_marksystemobject sp_MSreplcheck_connection
  2901. go
  2902. grant execute on dbo.sp_MSreplcheck_connection to public
  2903. go
  2904.  
  2905. raiserror('Creating procedure sp_MSreplcheck_pull', 0,1)
  2906. go
  2907.  
  2908. CREATE PROCEDURE sp_MSreplcheck_pull (
  2909. @publication sysname,
  2910. @raise_fatal_error bit = 1,
  2911. @pubid uniqueidentifier = NULL
  2912. )
  2913. AS
  2914.     -- sysadmin or db_owner have access
  2915.     if is_srvrolemember('sysadmin') = 1 or 
  2916.         is_member('db_owner') = 1
  2917.         return 0
  2918.  
  2919.     -- Need login_time to uniquely identify a connection.
  2920.     declare @login_time datetime
  2921.     select @login_time = login_time from master..sysprocesses where spid = @@spid
  2922.  
  2923.     -- If spid with publication in the cache, return success.
  2924.     if exists (select * from tempdb.dbo.MSpublisher_access where 
  2925.         spid = @@spid and
  2926.         login_time = @login_time and
  2927.         db_id = db_id() and
  2928.         publication = @publication)
  2929.         return (0)
  2930.  
  2931.     declare @has_access bit
  2932.     DECLARE @distribdb sysname
  2933.     DECLARE @distproc nvarchar (255)
  2934.     DECLARE @retcode int
  2935.     DECLARE @dist_rpcname sysname
  2936.     DECLARE @database sysname
  2937.     declare @login sysname
  2938.  
  2939.     select @login = suser_sname(suser_sid())
  2940.     select @database = db_name()
  2941.  
  2942.     EXEC @retcode = dbo.sp_helpdistributor     @rpcsrvname = @dist_rpcname OUTPUT,
  2943.                                            @distribdb   = @distribdb   OUTPUT
  2944.     IF @retcode <> 0 or @@error <> 0
  2945.     BEGIN
  2946.          RAISERROR (14071, 16, -1)
  2947.          return (1)
  2948.     END
  2949.  
  2950.     IF @retcode <> 0 OR @distribdb IS NULL OR @dist_rpcname IS NULL
  2951.     BEGIN
  2952.         RAISERROR (14071, 16, -1)
  2953.         return(1)
  2954.     END
  2955.  
  2956.     SELECT @distproc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access'
  2957.     EXEC @retcode = @distproc
  2958.          @publisher = @@SERVERNAME,
  2959.          @publisher_db = @database,
  2960.          @publication = @publication,
  2961.          @operation = 'check',
  2962.          @login = @login,
  2963.          @has_access = @has_access output
  2964.  
  2965.     IF @@error <> 0 OR @retcode <> 0
  2966.     BEGIN
  2967.         RAISERROR (14042, 16, -1)
  2968.         return (1)
  2969.     END
  2970.  
  2971.     if @has_access = 0
  2972.     begin
  2973.  
  2974.         -- We don't have access if we reach here, return error
  2975.         IF @raise_fatal_error = 1
  2976.             RAISERROR (21049, 14, -1, @login, @publication)
  2977.         ELSE
  2978.             RAISERROR (21049, 10, -1, @login, @publication)
  2979.         return(1)
  2980.     end
  2981.  
  2982. ADD_CACHE:
  2983.  
  2984.     -- If we are here, we know that the connection has access and is not in the cache
  2985.     -- add it in to the cache.
  2986.         
  2987.     -- Clear the cache to keep it small.
  2988.     exec @retcode = dbo.sp_MSflush_access_cache
  2989.     if @retcode <> 0 or @@error <> 0
  2990.         return (1)
  2991.             
  2992.     insert tempdb.dbo.MSpublisher_access
  2993.         (spid, db_id, publication, login_time, pubid) values
  2994.         (@@spid, db_id(), @publication, @login_time, @pubid)
  2995.  
  2996.     if @@error <> 0
  2997.         return (1)
  2998.  
  2999.     return (0)
  3000. GO
  3001.  
  3002. raiserror('Creating procedure sp_MSreplcheck_qv', 0, 1)
  3003. GO
  3004.  
  3005. create procedure sp_MSreplcheck_qv
  3006. as
  3007. begin
  3008.  
  3009.     set nocount on 
  3010.         
  3011.     declare @qv_replication varchar(10)
  3012.     declare @qv_engine varchar(10)
  3013.     declare @qv_value_replication integer
  3014.     declare @qv_value_engine integer
  3015.  
  3016.     select @qv_replication = '2745196162', @qv_engine = '845129433'
  3017.  
  3018.     exec @qv_value_replication = master.dbo.xp_qv @qv_replication     
  3019.     if @@ERROR <> 0 
  3020.         select @qv_value_replication = 1
  3021.  
  3022.     exec @qv_value_engine = master.dbo.xp_qv @qv_engine
  3023.     if @@ERROR <> 0
  3024.         select @qv_value_engine = 1
  3025.  
  3026.     -- magic number 1 assumes least common setting on all failure states
  3027.     select isnull( @qv_value_replication, 1 ) as VALUE_REPLICATION, isnull( @qv_value_engine, 1 ) as VALUE_ENGINE
  3028.  
  3029.  
  3030. end
  3031. go
  3032.  
  3033. exec dbo.sp_MS_marksystemobject sp_MSreplcheck_qv
  3034. go    
  3035.  
  3036. grant execute on dbo.sp_MSreplcheck_qv to public
  3037. go
  3038.  
  3039. raiserror('Creating procedure sp_reinitmergepullsubscription', 0, 1)
  3040. GO
  3041.  
  3042. create procedure sp_reinitmergepullsubscription
  3043.     @publisher        sysname  = 'all',
  3044.     @publisher_db    sysname  = 'all',
  3045.     @publication    sysname  = 'all'
  3046. AS
  3047.     declare @schemaversion            int
  3048.     declare @schematype                smallint
  3049.     declare @retcode                int
  3050.     declare @schemaguid                uniqueidentifier
  3051.     declare @pubname                sysname
  3052.     declare @publisher_name            sysname
  3053.     declare @pubdb                    sysname
  3054.     declare @pubid                    uniqueidentifier
  3055.     declare @subid                    uniqueidentifier
  3056.     declare @artid                    uniqueidentifier
  3057.     /*
  3058.     ** Replace 'all' with '%'
  3059.     */
  3060.  
  3061.     if LOWER(@publication) = 'all'
  3062.         SELECT @publication = '%'
  3063.  
  3064.     if LOWER(@publisher) = 'all'
  3065.         SELECT @publisher = '%'
  3066.  
  3067.     if LOWER(@publisher_db) = 'all'
  3068.         SELECT @publisher_db = '%'
  3069.     /*
  3070.     ** At subscriber side, we need to qualify the publication with server name and database name
  3071.     */
  3072.     IF NOT EXISTS (SELECT * FROM sysmergepublications WHERE name LIKE @publication 
  3073.         and ((@publisher = N'%') or (UPPER(publisher) = UPPER(@publisher))) 
  3074.         and publisher_db like @publisher_db)
  3075.         
  3076.         BEGIN
  3077.         IF @publication = '%'
  3078.                 RAISERROR (14008, 11, -1)
  3079.         ELSE
  3080.                 RAISERROR (20026, 11, -1, @publication)
  3081.         RETURN (1)
  3082.         END
  3083.     
  3084.     Declare SYN_CUR CURSOR LOCAL FAST_FORWARD FOR 
  3085.         select subs.subid, pubs.name, pubs.publisher, pubs.publisher_db 
  3086.             from sysmergepublications pubs, sysmergesubscriptions subs
  3087.                 where pubs.name LIKE  @publication
  3088.                     AND ((@publisher = '%') OR (UPPER(pubs.publisher) = UPPER(@publisher)))
  3089.                     AND pubs.publisher_db LIKE @publisher_db
  3090.                     AND pubs.pubid=subs.pubid
  3091.                     AND subs.pubid<>subs.subid
  3092.     FOR READ ONLY
  3093.     open SYN_CUR
  3094.     fetch SYN_CUR into @subid, @pubname, @publisher_name, @pubdb
  3095.     while (@@fetch_status<>-1)
  3096.     BEGIN
  3097.         exec @retcode=sp_MSCleanupForPullReinit @publication=@pubname, @publisher=@publisher_name, @publisher_db=@pubdb
  3098.         if @retcode<>0 or @@ERROR<>0
  3099.             return (1)
  3100.         update MSmerge_replinfo set schemaversion=-1, recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL 
  3101.             where repid=@subid  AND schemaversion is NOT NULL
  3102.         fetch next from SYN_CUR into @subid, @pubname, @publisher_name, @pubdb
  3103.             -- so that it won't be treated as a new susbscription    
  3104.     END
  3105.     close SYN_CUR
  3106.     deallocate SYN_CUR
  3107.     -- Forget that publisher ever sent us any generations.  They must be resent.
  3108.     -- Publication cleanup will remove the genhistory rows.
  3109.  
  3110.     if @publication = '%'
  3111.         -- get them all
  3112.         update MSmerge_replinfo set recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL
  3113.     else
  3114.         begin
  3115.         select @pubid = pubid from sysmergepublications where name = @publication
  3116.         update MSmerge_replinfo set recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL
  3117.             where repid in (select subid from sysmergesubscriptions where pubid = @pubid)
  3118.         end
  3119. GO
  3120.  
  3121. exec dbo.sp_MS_marksystemobject sp_reinitmergepullsubscription
  3122. go    
  3123. grant execute on dbo.sp_reinitmergepullsubscription to public
  3124.  
  3125. raiserror('Creating procedure sp_MSreplcheck_subscribe', 0,1)
  3126. go
  3127.  
  3128. CREATE PROCEDURE sp_MSreplcheck_subscribe
  3129. AS
  3130.     /*
  3131.     ** Only the System Administratr (SA) or the Database Owner (dbo) 
  3132.     ** can subscribe from the subscribing database.
  3133.     */
  3134.     if  is_srvrolemember('sysadmin') <> 1 and is_member ('db_owner') <> 1 
  3135.         BEGIN
  3136.             RAISERROR (21050, 14, -1)
  3137.             RETURN (1)
  3138.         END
  3139. GO
  3140.  
  3141. raiserror('Creating procedure sp_MSreplicationcompatlevel', 0,1)
  3142. GO
  3143. create procedure sp_MSreplicationcompatlevel
  3144. @dbname             sysname,
  3145. @cmptlevel            float(8)
  3146. As
  3147.     declare        @is_distdb    smallint
  3148.  
  3149.     select @is_distdb = 0
  3150.  
  3151.     IF EXISTS (select * from msdb..sysobjects where name='MSdistributiondbs')
  3152.         begin
  3153.             IF EXISTS (SELECT * FROM msdb..MSdistributiondbs where name=@dbname)
  3154.                 select @is_distdb = 1
  3155.         end
  3156.         
  3157.     /*
  3158.     ** Parameter check
  3159.     ** @dbname
  3160.     */
  3161.     IF NOT EXISTS (SELECT * FROM master.dbo.sysdatabases WHERE
  3162.         name = @dbname)
  3163.     BEGIN
  3164.         RAISERROR(15010, 16, -1, @dbname)
  3165.         RETURN(2)
  3166.     END
  3167.  
  3168.     /*
  3169.     ** Parameter check. NOTE
  3170.     ** @cmptlevel
  3171.     */
  3172.     IF @cmptlevel<6.0
  3173.     BEGIN
  3174.         RAISERROR(20060,16,-1)
  3175.         RETURN(2)
  3176.     END
  3177.  
  3178.     /*
  3179.     ** If cmptlevel is lower than 7.0, special attention should be paid. 
  3180.     ** If current database is a distribution database or is involed in merge
  3181.     ** replication, then it can not be set to a level lower than 7.0.
  3182.     */
  3183.     
  3184.     create table #tmp (any_merge smallint NOT NULL)
  3185.     insert into #tmp exec ('select count(*) from ' + @dbname + '..sysobjects where name=' + '''sysmergesubscriptions''' )
  3186.     if (exists(select any_merge from #tmp where any_merge>0) OR @is_distdb = 1) 
  3187.                 AND (@cmptlevel<7.0) 
  3188.         begin
  3189.             drop table #tmp
  3190.             return 1
  3191.         end
  3192.     else 
  3193.         begin
  3194.             drop table #tmp
  3195.             return 0
  3196.         end
  3197. go
  3198.  
  3199. exec dbo.sp_MS_marksystemobject sp_MSreplicationcompatlevel
  3200. go
  3201.  
  3202. raiserror('Creating procedure sp_MSgenreplnickname', 0,1)
  3203. GO
  3204.  
  3205. create procedure sp_MSgenreplnickname
  3206.             @srcguid    uniqueidentifier,    /* Source Guid */
  3207.             @repnick    int    output    /* nickname */
  3208.     as
  3209.     declare @binguid binary(16)
  3210.     declare    @nickname        int
  3211.     set @binguid = convert(binary(16), @srcguid)
  3212.     select @nickname = convert(int, convert(binary(4),substring( convert(nchar(8),@binguid), 1, 2)))
  3213.     while exists (select replnickname from MSmerge_replinfo where replnickname = @nickname)
  3214.         select @nickname = @nickname + 1
  3215.     select @repnick = @nickname
  3216. go
  3217.  
  3218. exec dbo.sp_MS_marksystemobject sp_MSgenreplnickname
  3219. go
  3220. grant execute on dbo.sp_MSgenreplnickname to public
  3221.  
  3222. raiserror('Creating procedure sp_MSmergesubscribedb', 0,1)
  3223. GO
  3224.  
  3225. CREATE PROCEDURE sp_MSmergesubscribedb(
  3226.     @value sysname
  3227.     ) AS
  3228.  
  3229.     SET NOCOUNT ON
  3230.  
  3231.     /*
  3232.     ** Declarations.
  3233.     */
  3234.     declare @retcode                 int
  3235.     
  3236.  
  3237.     /*
  3238.     ** Security Check
  3239.     */
  3240.  
  3241.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  3242.     IF @@ERROR <> 0 or @retcode <> 0
  3243.         RETURN(1)
  3244.  
  3245.  
  3246.     /*
  3247.     ** Initialization
  3248.     */
  3249.  
  3250.  
  3251.     /*
  3252.     ** Parameter check
  3253.     ** @value
  3254.     */
  3255.     IF LOWER(@value) NOT IN ('true','false')
  3256.     BEGIN
  3257.       RAISERROR(14137,16,-1)
  3258.       RETURN(1)
  3259.     END
  3260.  
  3261.     IF LOWER(@value) = 'true'
  3262.         BEGIN        
  3263.             execute @retcode = dbo.sp_MScreate_mergesystables
  3264.             if @@ERROR <> 0 or @retcode <> 0
  3265.                 begin
  3266.                     return (1)
  3267.                 end
  3268.         END
  3269.     
  3270.     -- We assume we will do nothing about disabling a subscriber
  3271.     
  3272. GO
  3273.  
  3274. exec dbo.sp_MS_marksystemobject sp_MSmergesubscribedb
  3275. go
  3276.  
  3277. grant execute on dbo.sp_MSmergesubscribedb to public
  3278. go 
  3279.  
  3280. raiserror('Creating procedure sp_MSenumallpublications', 0,1)
  3281. go
  3282.  
  3283. CREATE PROCEDURE sp_MSenumallpublications(
  3284. @publisherdb sysname = '%', 
  3285. @replication_type tinyint = 1,
  3286. @agent_login sysname = NULL,
  3287. @security_check bit = 1 -- Security check by default so that things depending on security 
  3288.                         -- filtering will not break immediately
  3289. )
  3290.  
  3291. as
  3292.     set nocount on
  3293.     declare @dbname         sysname
  3294.     declare @trans             tinyint
  3295.     declare @merge             tinyint
  3296.     declare @3rdparty        tinyint
  3297.     declare @retcode        int
  3298.     DECLARE @dist_rpcname    sysname
  3299.     declare @distribdb        sysname
  3300.     declare @login            sysname
  3301.     declare @proc            nvarchar(255)
  3302.     declare @distbit        int
  3303.     declare @is_user_admin    bit
  3304.     declare @same_as_user    bit
  3305.  
  3306.     -- UI: If the distributor is not installed, return empty result
  3307.     if not exists (SELECT * FROM master..sysservers
  3308.               WHERE  srvstatus & 8 <> 0)
  3309.         return (0)
  3310.  
  3311.     -- UI: Win95 subscriber will send in null agent_login
  3312.     -- Assume the agent login to be the current login if it is NT login
  3313.     if @security_check = 1 and @agent_login is null
  3314.         and not exists (select * from master.dbo.syslogins where
  3315.             sid = suser_sid() and 
  3316.             isntname = 0)
  3317.         select @agent_login = suser_sname(suser_sid())
  3318.  
  3319.     /* Initializations */
  3320.     select @trans = 1 
  3321.     select @merge = 2
  3322.     select @3rdparty = 0
  3323.     select @login = suser_sname(suser_sid())
  3324.     SELECT @distbit = 16
  3325.     select @is_user_admin = 0
  3326.     select @same_as_user = 0
  3327.  
  3328.     -- Get publication list
  3329.     create table #pubdbs (publisher_db sysname NOT NULL, replication_type int NOT NULL)
  3330.  
  3331.     /* Return everything if @replication_type is not in (@3rdparty, @trans, @merge) */
  3332.     if not @replication_type in (@3rdparty, @trans, @merge)
  3333.         select @replication_type = null
  3334.  
  3335.     if @replication_type = @trans or @replication_type is null
  3336.         insert into #pubdbs select name, @trans from master..sysdatabases where 
  3337.             name like @publisherdb and category & 1 <> 0 and 
  3338.             (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0) and 
  3339.             has_dbaccess(name) = 1
  3340.     if @replication_type = @merge or @replication_type is null
  3341.         insert into #pubdbs select name, @merge from master..sysdatabases where 
  3342.             name like @publisherdb and category & 4 <> 0 and 
  3343.             (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0) and 
  3344.             has_dbaccess(name) = 1
  3345.     if @replication_type = @3rdparty
  3346.         insert into #pubdbs select name, @3rdparty from master..sysdatabases where 
  3347.             name like @publisherdb and category & @distbit <> 0 and 
  3348.             (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0) and 
  3349.             has_dbaccess(name) = 1
  3350.  
  3351.     create table #MSenumpublications 
  3352.             (publisher_db sysname NOT NULL, publication sysname NOT NULL, replication_type tinyint NOT NULL, 
  3353.             immediate_sync bit NOT NULL, allow_pull bit NOT NULL, allow_anonymous bit NOT NULL, 
  3354.             enabled_for_internet bit NOT NULL, repl_freq tinyint NOT NULL, immediate_sync_ready bit NOT NULL, 
  3355.             allow_sync_tran bit NOT NULL, independent_agent bit NOT NULL, is_db_owner int NOT NULL, 
  3356.             thirdparty_flag bit NOT NULL, vendor_name sysname NULL, publisher sysname NULL, description nvarchar(255) NULL, distribution_db sysname NULL)
  3357.  
  3358.     declare hCForEachDb CURSOR LOCAL FAST_FORWARD FOR select publisher_db, replication_type from  #pubdbs
  3359.     FOR READ ONLY
  3360.     open hCForEachDb
  3361.     fetch hCForEachDb into @dbname, @replication_type
  3362.     /* Loop for each database */
  3363.     while (@@fetch_status >= 0) 
  3364.     begin
  3365.         if (@replication_type) = @trans
  3366.             select @proc = quotename(@dbname) + '.dbo.sp_MSenumtranpublications'
  3367.         else if (@replication_type) = @merge
  3368.             select @proc = quotename(@dbname) + '.dbo.sp_MSenummergepublications'
  3369.         else if (@replication_type) = @3rdparty
  3370.             select @proc = quotename(@dbname) + '.dbo.sp_MSenum3rdpartypublications'
  3371.         insert into #MSenumpublications exec @retcode = @proc
  3372.         if @@ERROR <> 0 or @retcode <> 0
  3373.             return (1)
  3374.         fetch hCForEachDb into @dbname, @replication_type
  3375.     end /* while FETCH_SUCCESS */
  3376.  
  3377.     -- Prepare for filtering.
  3378.     create table #admin_publications (publisher_db sysname not null, 
  3379.         publication sysname not null)
  3380.  
  3381.     create table #agent_publications (publisher_db sysname not null,
  3382.         publication sysname not null)
  3383.  
  3384.  
  3385.     IF (@security_check <> 0)
  3386.     BEGIN
  3387.     
  3388.         EXEC @retcode = dbo.sp_helpdistributor     @rpcsrvname = @dist_rpcname OUTPUT,
  3389.                                                @distribdb   = @distribdb   OUTPUT
  3390.  
  3391.         IF @@error <> 0 OR @retcode <> 0
  3392.             RETURN (1)
  3393.  
  3394.         IF @distribdb is null
  3395.         BEGIN
  3396.             RAISERROR (14071, 16, -1)
  3397.             RETURN (1)
  3398.         END
  3399.  
  3400.         SELECT @proc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access'
  3401.  
  3402.         -- Optimization
  3403.         if is_srvrolemember('sysadmin') = 1
  3404.             select @is_user_admin = 1
  3405.         else
  3406.             insert into #admin_publications EXEC @retcode = @proc
  3407.                  @publisher = @@SERVERNAME,
  3408.                  @operation = 'get_publications',
  3409.                  @login = @login
  3410.  
  3411.  
  3412.         if suser_sid(@agent_login) = suser_sid()
  3413.             select @same_as_user = 1
  3414.         else
  3415.             insert into #agent_publications EXEC @retcode = @proc
  3416.                 @publisher = @@SERVERNAME,
  3417.                 @operation = 'get_publications',
  3418.                 @login = @agent_login
  3419.         
  3420.     END -- IF (@security_check <> 0) 
  3421.  
  3422.     -- workaround of a server bug of leaving tran open when
  3423.     -- insert into exec failed.
  3424.     while(@@trancount <> 0) commit tran
  3425.  
  3426. DONE2:
  3427.  
  3428.     select pub.publisher_db, pub.publication, pub.replication_type, 
  3429.             pub.immediate_sync, pub.allow_pull, pub.allow_anonymous, 
  3430.             pub.enabled_for_internet, pub.repl_freq, pub.immediate_sync_ready, 
  3431.             pub.allow_sync_tran, pub.independent_agent, N'agent_access' = case 
  3432.                 when 
  3433.                     (@same_as_user = 1 or
  3434.                     exists (select * from #agent_publications agent where
  3435.                     agent.publisher_db = pub.publisher_db and
  3436.                     agent.publication = pub.publication))
  3437.                     then convert(bit,1)
  3438.                 else convert(bit,0)
  3439.                 end,
  3440.             pub.thirdparty_flag,
  3441.             pub.vendor_name, pub.publisher, pub.description, pub.distribution_db
  3442.      from #MSenumpublications pub where exists (select * from #admin_publications admin where
  3443.         pub.publisher_db = admin.publisher_db and
  3444.         pub.publication = admin.publication) or
  3445.         @security_check = 0 or
  3446.         pub.is_db_owner = 1 or
  3447.         @is_user_admin = 1
  3448.      order by pub.publication, pub.publisher_db
  3449.  
  3450.     return (0)
  3451. go
  3452.  
  3453. grant execute on dbo.sp_MSenumallpublications to public
  3454. go 
  3455.  
  3456. raiserror('Creating procedure sp_MSenumtranpublications', 0,1)
  3457. go
  3458.  
  3459. CREATE PROCEDURE sp_MSenumtranpublications
  3460. as
  3461.     set nocount on
  3462.     select db_name(), name, 1, immediate_sync, allow_pull, allow_anonymous, 
  3463.         enabled_for_internet, repl_freq, immediate_sync_ready, 
  3464.         allow_sync_tran, independent_agent, is_member('db_owner'),
  3465.         0, -- thirdparty
  3466.         'Microsoft SQL Server', @@servername, description,
  3467.         convert(sysname, null)
  3468.         from syspublications pubs
  3469.         where exists (select * from sysarticles art where pubs.pubid = art.pubid) 
  3470.             and status <> 0
  3471. go
  3472.  
  3473.  
  3474. raiserror('Creating procedure sp_MSenummergepublications', 0,1)
  3475. go
  3476.  
  3477. CREATE PROCEDURE sp_MSenummergepublications
  3478.  
  3479. as
  3480.     set nocount on
  3481.     select db_name(), name, 2, 1, allow_pull, allow_anonymous, enabled_for_internet, 0, snapshot_ready, 0, 1, is_member('db_owner'),
  3482.         0, --thirdparty
  3483.         'Microsoft SQL Server', publisher, description,
  3484.         convert(sysname, null)
  3485.         from 
  3486.         sysmergepublications where status <> 0
  3487. go
  3488.  
  3489. raiserror('Creating procedure sp_MSenum3rdpartypublications', 0,1)
  3490. go
  3491.  
  3492. CREATE PROCEDURE sp_MSenum3rdpartypublications
  3493. as
  3494.     set nocount on
  3495.     select pubs.publisher_db, publication, 
  3496.         case when publication_type <> 2 then 1
  3497.         else 2
  3498.         end,  --replication_type, 1 tran, 2 merge ; pub type 0 tran 1 snapshot, 2 merge
  3499.         immediate_sync, allow_pull, allow_anonymous, 
  3500.         0,    --enabled_for_internet,
  3501.         case when publication_type = 0 then 0
  3502.         else 1
  3503.         end,  --repl_freq, 
  3504.         1,    --immediate_sync_ready, always return 1 so that UI will not warn
  3505.         0,    -- allow_sync_tran, 
  3506.         independent_agent, 
  3507.         is_member('db_owner'),
  3508.         1, --thirdparty
  3509.         pubs.vendor_name,
  3510.         srv.srvname,
  3511.         pubs.description,
  3512.         db_name()
  3513.  
  3514.         from MSpublications pubs, master..sysservers srv
  3515.         where exists (select * from MSarticles art where 
  3516.                 pubs.publication_id = art.publication_id)  and
  3517.             thirdparty_flag <> 0 and
  3518.             publisher_id = srvid
  3519. go
  3520.  
  3521.  
  3522. dump tran master with no_log
  3523. GO
  3524.  
  3525. raiserror('Creating procedure sp_reinitpullsubscription', 0,1)
  3526. go
  3527.  
  3528. CREATE PROCEDURE sp_reinitpullsubscription (
  3529.     @publisher sysname,
  3530.     @publisher_db sysname,
  3531.     @publication sysname = 'all'                       /* publication name */
  3532.     )AS
  3533.  
  3534.     SET NOCOUNT ON
  3535.     
  3536.     declare @subscription_type int    
  3537.     declare @sync_type tinyint
  3538.     /*
  3539.     ** Security Check
  3540.     */
  3541.     
  3542.       declare @retcode     int  
  3543.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  3544.     IF @@ERROR <> 0 or @retcode <> 0
  3545.         RETURN(1)
  3546.  
  3547.     /*
  3548.     ** Initializations.
  3549.     */
  3550.    
  3551.     /*
  3552.     ** Parameter Check: @publisher
  3553.     ** Check to make sure that the publisher is define
  3554.     */
  3555.     IF @publisher IS NULL
  3556.     BEGIN
  3557.         RAISERROR (14043, 16, -1, '@publisher')
  3558.         RETURN (1)
  3559.     END
  3560.  
  3561.     IF @publisher = 'all'
  3562.     BEGIN
  3563.         RAISERROR (14136, 16, -1)
  3564.         RETURN (1)
  3565.     END
  3566.  
  3567.     EXECUTE @retcode = dbo.sp_validname @publisher
  3568.  
  3569.     IF @@ERROR <> 0 OR @retcode <> 0
  3570.        RETURN (1)
  3571.     
  3572.  
  3573.     /*
  3574.     ** Parameter Check: @publisher_db
  3575.     */
  3576.  
  3577.     IF @publisher_db IS NULL
  3578.     BEGIN
  3579.         RAISERROR (14043, 16, -1, '@publisher_db')
  3580.         RETURN (1)
  3581.     END
  3582.  
  3583.     IF @publisher_db = 'all'
  3584.     BEGIN
  3585.         RAISERROR (14136, 16, -1)
  3586.         RETURN (1)
  3587.     END
  3588.  
  3589.     EXECUTE @retcode = dbo.sp_validname @publisher_db
  3590.  
  3591.     IF @@ERROR <> 0 OR @retcode <> 0
  3592.        RETURN (1)
  3593.  
  3594.     /*
  3595.     ** Parameter Check: @publication
  3596.     ** 
  3597.     */
  3598.     IF @publication IS NULL
  3599.     BEGIN
  3600.         RAISERROR (14043, 16, -1, '@publication')
  3601.         RETURN (1)
  3602.     END
  3603.  
  3604.     IF LOWER(@publication) = 'all'
  3605.         select @publication = '%'
  3606.     ELSE
  3607.     BEGIN
  3608.         EXECUTE @retcode = dbo.sp_validname @publication
  3609.  
  3610.         IF @@ERROR <> 0 OR @retcode <> 0
  3611.         RETURN (1)
  3612.     END
  3613.         
  3614.     IF NOT EXISTS (SELECT * FROM  MSreplication_subscriptions 
  3615.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  3616.                       publisher_db  = @publisher_db AND
  3617.                       publication like @publication )
  3618.     BEGIN
  3619.             RAISERROR(14135, 11, -1,  @publisher, @publisher_db, @publication)
  3620.             RETURN(1)
  3621.     END
  3622.         
  3623.     select @sync_type = immediate_sync 
  3624.         from MSreplication_subscriptions
  3625.         WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db  = @publisher_db AND publication like @publication 
  3626.  
  3627.     IF @sync_type = 0
  3628.     BEGIN
  3629.         raiserror(21059, 16, -1)
  3630.         return (1)
  3631.     END
  3632.         
  3633.     UPDATE MSreplication_subscriptions set 
  3634.         transaction_timestamp = 0x00
  3635.         WHERE UPPER(publisher) = UPPER(@publisher) AND
  3636.                       publisher_db  = @publisher_db AND
  3637.                       publication like @publication 
  3638.     if @@ERROR<>0 
  3639.         RETURN (1)
  3640. GO
  3641.  
  3642. grant execute on dbo.sp_reinitpullsubscription to public
  3643. go
  3644.     
  3645. raiserror('Creating procedure sp_addpullsubscription', 0,1)
  3646. go
  3647.  
  3648. CREATE PROCEDURE sp_addpullsubscription (
  3649.     @publisher sysname,
  3650.     @publisher_db sysname,
  3651.     @publication sysname,    /* publication name */
  3652.     @independent_agent nvarchar(5) = 'true',  /* true or false */
  3653.     @subscription_type nvarchar(9) = 'anonymous',     /* subscription_type, pull or anonymous */
  3654.     @description nvarchar(100) = NULL,
  3655.     -- SyncTran
  3656.     @update_mode          nvarchar(15) = 'read only', -- Can be 'read only', 'sync tran'
  3657.     @immediate_sync        bit = 1
  3658.      ) AS
  3659.  
  3660.     SET NOCOUNT ON
  3661.  
  3662.     /*
  3663.     ** Declarations.
  3664.     */
  3665.  
  3666.     DECLARE @retcode int
  3667.     DECLARE @subscription_type_id int   /* 1 = pull, 2 = anonymous */
  3668.     DECLARE @independent_agent_id bit
  3669.     -- SyncTran
  3670.     DECLARE @update_mode_id     tinyint 
  3671.  
  3672.  
  3673.     /* 
  3674.     ** Check if replication components are installed on this server
  3675.     */
  3676.     exec @retcode = dbo.sp_MS_replication_installed
  3677.     if (@retcode <> 1)
  3678.     begin
  3679.         return (1)
  3680.     end
  3681.     
  3682.     /*
  3683.     ** Security Check
  3684.     */
  3685.  
  3686.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  3687.     IF @@ERROR <> 0 or @retcode <> 0
  3688.         RETURN(1)
  3689.  
  3690.     /*
  3691.     ** Initializations.
  3692.     */
  3693.  
  3694.     /*
  3695.     ** Parameter Check: @publisher
  3696.     ** Check to make sure that the publisher is define
  3697.     */
  3698.     IF @publisher IS NULL
  3699.     BEGIN
  3700.         RAISERROR (14043, 16, -1, '@publisher')
  3701.         RETURN (1)
  3702.     END
  3703.  
  3704.     IF @publisher = 'all'
  3705.     BEGIN
  3706.         RAISERROR (14136, 16, -1)
  3707.         RETURN (1)
  3708.     END
  3709.  
  3710.     EXECUTE @retcode = dbo.sp_validname @publisher
  3711.  
  3712.     IF @@ERROR <> 0 OR @retcode <> 0
  3713.        RETURN (1)
  3714.     
  3715.  
  3716.     /*
  3717.     ** Parameter Check: @publisher_db
  3718.     */
  3719.  
  3720.     IF @publisher_db IS NULL
  3721.     BEGIN
  3722.         RAISERROR (14043, 16, -1, '@publisher_db')
  3723.         RETURN (1)
  3724.     END
  3725.  
  3726.     IF @publisher_db = 'all'
  3727.     BEGIN
  3728.         RAISERROR (14136, 16, -1)
  3729.         RETURN (1)
  3730.     END
  3731.  
  3732.     EXECUTE @retcode = dbo.sp_validname @publisher_db
  3733.  
  3734.     IF @@ERROR <> 0 OR @retcode <> 0
  3735.        RETURN (1)
  3736.  
  3737.     /*
  3738.     ** Parameter Check: @publication
  3739.     ** 
  3740.     */
  3741.     IF @publication IS NULL
  3742.     BEGIN
  3743.         RAISERROR (14043, 16, -1, '@publication')
  3744.         RETURN (1)
  3745.     END
  3746.  
  3747.     IF @publication = 'all'
  3748.     BEGIN
  3749.         RAISERROR (14136, 16, -1)
  3750.         RETURN (1)
  3751.     END
  3752.  
  3753.     EXECUTE @retcode = dbo.sp_validname @publication
  3754.  
  3755.     IF @@ERROR <> 0 OR @retcode <> 0
  3756.        RETURN (1)
  3757.  
  3758.     IF @independent_agent IS NULL OR LOWER(@independent_agent) NOT IN ('true', 'false')
  3759.         BEGIN
  3760.             RAISERROR (14148, 16, -1, '@independent_agent')
  3761.             RETURN (1)
  3762.         END
  3763.  
  3764.     IF LOWER(@independent_agent) = 'true' SELECT @independent_agent_id = 1
  3765.     ELSE SELECT @independent_agent_id = 0
  3766.     /*
  3767.     ** Parameter Check:  @subscription_type
  3768.     ** The @status value can be:
  3769.     **
  3770.     **      type_id            type
  3771.     **      ======            ========
  3772.     **             0              push
  3773.     **           1            pull
  3774.     **           2            anonymous
  3775.     **
  3776.     **    Note: @subscription_type = push is only used by distribution agents
  3777.     */
  3778.     
  3779.     IF @subscription_type IS NULL OR LOWER(@subscription_type) NOT IN ('push', 'pull','anonymous')
  3780.     BEGIN
  3781.         RAISERROR (20016, 16, -1)
  3782.         RETURN (1)
  3783.     END
  3784.  
  3785.  
  3786.     IF LOWER(@subscription_type) = 'pull'    
  3787.         SELECT @subscription_type_id = 1
  3788.     ELSE IF LOWER(@subscription_type) = 'anonymous'  
  3789.         SELECT @subscription_type_id = 2
  3790.     ELSE
  3791.         SELECT @subscription_type_id = 0
  3792.  
  3793.     IF @independent_agent_id = 0 AND @subscription_type_id = 2
  3794.     BEGIN
  3795.         RAISERROR (21026, 16, -1)
  3796.         RETURN (1)
  3797.     END
  3798.  
  3799.     -- SyncTran
  3800.     /*
  3801.     **  Parameter check: @update_mode
  3802.     */
  3803.     IF @update_mode IS NULL OR LOWER(@update_mode) NOT IN ('read only', 'sync tran')
  3804.     BEGIN
  3805.         RAISERROR (20502, 16, -1, '@update_mode')
  3806.         RETURN (1)
  3807.     END
  3808.  
  3809.     IF LOWER(@update_mode) = 'sync tran' 
  3810.         begin
  3811.                SELECT @update_mode_id = 1
  3812.                if @subscription_type_id = 2  -- Anonymous subscriptions should not be allowed to 
  3813.                    begin                      -- subscribe with 'synctran option'    
  3814.                        RAISERROR (21057, 16, -1)
  3815.                     RETURN (1)
  3816.                 end
  3817.         end    
  3818.     ELSE 
  3819.         SELECT @update_mode_id = 0
  3820.     -- SyncTran
  3821.  
  3822.     begin tran
  3823.     save TRAN addpullsubscription
  3824.     
  3825.     /* 
  3826.     ** Check to see if MSreplication_subscriptions and MSsubscription_properties 
  3827.     ** tables exists.
  3828.     ** If not, create it.
  3829.     */
  3830.     exec @retcode = dbo.sp_MScreate_sub_tables
  3831.         @tran_sub_table = 1,
  3832.         @property_table = 1
  3833.     IF @@ERROR <> 0 or @retcode <> 0
  3834.         goto UNDO
  3835.     
  3836.     /*
  3837.     ** Check to make sure that the subscription does not already exist
  3838.     */
  3839.     -- Delete the push subscription entry first. If may be obsolete and left by 
  3840.     -- defunct push agents
  3841.     delete MSreplication_subscriptions 
  3842.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  3843.                       publisher_db  = @publisher_db AND
  3844.                       publication = @publication and
  3845.                       subscription_type = 0
  3846.     if @@error <> 0
  3847.         goto UNDO
  3848.  
  3849.     -- It is not allowed to subscribe to the same publication twice even with
  3850.     -- differnet publication type. 
  3851.     IF EXISTS (SELECT * FROM  MSreplication_subscriptions 
  3852.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  3853.                       publisher_db  = @publisher_db AND
  3854.                       publication = @publication)
  3855.                       /*
  3856.                          OR
  3857.                       -- If the subscription is already added by the distribution agent
  3858.                       (@independent_agent_id = 0 AND 
  3859.                       (publication IS NULL OR
  3860.                       publication = ''))) AND
  3861.                       independent_agent = @independent_agent_id AND
  3862.                       subscription_type = @subscription_type_id) */
  3863.     BEGIN
  3864.         RAISERROR (14058, 16, -1)
  3865.         GOTO UNDO
  3866.     END
  3867.  
  3868.   
  3869.     /*
  3870.     ** Add the subscription
  3871.     */
  3872.  
  3873.     INSERT MSreplication_subscriptions  (publisher,
  3874.                                     publisher_db,
  3875.                                     publication,
  3876.                                     independent_agent,
  3877.                                     subscription_type,
  3878.                                     distribution_agent,
  3879.                                     description,
  3880.                                     time,
  3881.                                     transaction_timestamp,
  3882.                                     -- SyncTran
  3883.                                     update_mode,
  3884.                                     immediate_sync)
  3885.        VALUES (@publisher,
  3886.                    @publisher_db,
  3887.                    @publication,
  3888.                    @independent_agent_id,    
  3889.                    @subscription_type_id,
  3890.                    NULL,
  3891.                    @description,
  3892.                    getdate(),
  3893.                    0,
  3894.                    -- SyncTran
  3895.                    @update_mode_id,
  3896.                    @immediate_sync
  3897.                    )
  3898.     IF @@ERROR <> 0
  3899.     BEGIN
  3900.        RAISERROR (14057, 16, -1)
  3901.        GOTO UNDO
  3902.     END
  3903.  
  3904.     COMMIT TRAN
  3905.  
  3906.     RETURN (0)
  3907.  
  3908. UNDO:
  3909.     IF @@TRANCOUNT > 0
  3910.     begin
  3911.         ROLLBACK TRAN addpullsubscription
  3912.         COMMIT TRAN   
  3913.     end
  3914.     return 1
  3915. go
  3916.  
  3917.  
  3918. raiserror('Creating procedure sp_addpullsubscription_agent', 0,1)
  3919. go
  3920.  
  3921. CREATE PROCEDURE sp_addpullsubscription_agent (
  3922.     @publisher sysname,
  3923.     @publisher_db sysname,
  3924.     @publication sysname,         /* publication name */
  3925.     @subscriber sysname    = NULL,
  3926.     @subscriber_db sysname = NULL,
  3927.     @subscriber_security_mode        int = NULL,                        /* 0 standard; 1 integrated */
  3928.     @subscriber_login                sysname = NULL,
  3929.     @subscriber_password            sysname = NULL,
  3930.     @distributor sysname = @publisher,
  3931.     @distribution_db sysname = NULL,
  3932.     @distributor_security_mode int = 0,
  3933.     @distributor_login sysname = 'sa',
  3934.     @distributor_password sysname = NULL,
  3935.     @optional_command_line nvarchar(4000) = '',
  3936.     @frequency_type  int = 2 ,  /* 2== OnDemand */
  3937.     @frequency_interval int = 1, 
  3938.     @frequency_relative_interval int = 1, 
  3939.     @frequency_recurrence_factor int = 1, 
  3940.     @frequency_subday int = 1, 
  3941.     @frequency_subday_interval int = 1 ,
  3942.     @active_start_time_of_day int = 0, 
  3943.     @active_end_time_of_day int = 0,         
  3944.     @active_start_date int = 0, 
  3945.     @active_end_date int =0,
  3946.     @distribution_jobid    binary(16) = NULL OUTPUT,
  3947.     @encrypted_distributor_password bit = 0,
  3948.     @enabled_for_syncmgr nvarchar(5) = 'false', /* Enabled for SYNCMGR: true or false */
  3949.     @ftp_address sysname = NULL,
  3950.     @ftp_port int = NULL,
  3951.     @ftp_login sysname = NULL,
  3952.     @ftp_password sysname = NULL
  3953.     ) AS
  3954.  
  3955.     SET NOCOUNT ON
  3956.  
  3957.     /*
  3958.     ** Declarations.
  3959.     */
  3960.  
  3961.     DECLARE @command nvarchar(4000)
  3962.     DECLARE @name nvarchar(255)
  3963.     DECLARE @retcode int
  3964.     DECLARE @subscription_type_id int   /* 1 = pull, 2 = anonymous */
  3965.     DECLARE @independent_agent_id bit
  3966.     DECLARE @distribution_agent nvarchar(100)
  3967.     DECLARE @category_name sysname
  3968.     DECLARE @platform_nt binary
  3969.     DECLARE @subscriber_enc_password sysname
  3970.     select @platform_nt = 0x1
  3971.  
  3972.     /*
  3973.     ** Security Check
  3974.     */
  3975.  
  3976.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  3977.     IF @@ERROR <> 0 or @retcode <> 0
  3978.         RETURN(1)
  3979.  
  3980.     /*
  3981.     ** Initializations.
  3982.     */
  3983.  
  3984.     -- Set null @optional_command_line to empty string to avoid string concat problem
  3985.     if @optional_command_line is null
  3986.         set @optional_command_line = ''
  3987.  
  3988.     IF @distributor_password = N''
  3989.         select @distributor_password = NULL
  3990.  
  3991.     IF @ftp_password = N''
  3992.         select @ftp_password = NULL
  3993.  
  3994.     /*
  3995.     ** Parameter Check: @publisher
  3996.     ** Check to make sure that the publisher is define
  3997.     */
  3998.     IF @publisher IS NULL
  3999.     BEGIN
  4000.         RAISERROR (14043, 16, -1, '@publisher')
  4001.         RETURN (1)
  4002.     END
  4003.  
  4004.     EXECUTE @retcode = dbo.sp_validname @publisher
  4005.  
  4006.     IF @@ERROR <> 0 OR @retcode <> 0
  4007.        RETURN (1)
  4008.     
  4009.  
  4010.     /*
  4011.     ** Parameter Check: @publisher_db
  4012.     */
  4013.  
  4014.     IF @publisher_db IS NULL
  4015.     BEGIN
  4016.         RAISERROR (14043, 16, -1, '@publisher_db')
  4017.         RETURN (1)
  4018.     END
  4019.  
  4020.     EXECUTE @retcode = dbo.sp_validname @publisher_db
  4021.  
  4022.     IF @@ERROR <> 0 OR @retcode <> 0
  4023.        RETURN (1)
  4024.  
  4025.     /*
  4026.     ** Parameter Check: @publication
  4027.     ** 
  4028.     */
  4029.     IF @publication IS NULL
  4030.     BEGIN
  4031.         RAISERROR (14043, 16, -1, '@publication')
  4032.         RETURN (1)
  4033.     END
  4034.  
  4035.     EXECUTE @retcode = dbo.sp_validname @publication
  4036.  
  4037.     IF @@ERROR <> 0 OR @retcode <> 0
  4038.        RETURN (1)
  4039.  
  4040.     /*
  4041.     ** Parameter Check: @subscriber and @subscriber_db
  4042.     */
  4043.  
  4044.     if @subscriber IS NULL or rtrim(@subscriber) = ''
  4045.         SELECT @subscriber = @@SERVERNAME
  4046.  
  4047.     if @subscriber_db IS NULL or rtrim(@subscriber_db) = ''
  4048.         SELECT @subscriber_db = DB_NAME()
  4049.     
  4050.     EXECUTE @retcode = dbo.sp_validname @subscriber
  4051.     IF @@ERROR <> 0 OR @retcode <> 0
  4052.        RETURN (1)
  4053.     
  4054.     EXECUTE @retcode = dbo.sp_validname @subscriber_db
  4055.     IF @@ERROR <> 0 OR @retcode <> 0
  4056.        RETURN (1)
  4057.  
  4058.     /* 
  4059.     ** Check to see if MSreplictaion_subscriptions table exists.
  4060.     ** If so, copy it into the temp table
  4061.     */
  4062.     IF  NOT EXISTS (SELECT * FROM sysobjects WHERE 
  4063.         type = 'U' AND
  4064.         name = 'MSreplication_subscriptions')
  4065.     BEGIN
  4066.         RAISERROR (20017, 16, -1)
  4067.         RETURN (1)
  4068.     END    
  4069.     
  4070.     /*
  4071.     ** Check to make sure that the subscription does  exist
  4072.     */
  4073.     IF NOT EXISTS (SELECT * FROM  MSreplication_subscriptions
  4074.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  4075.                       publisher_db  = @publisher_db AND
  4076.                       publication = @publication)
  4077.     BEGIN
  4078.         RAISERROR (20017, 16, -1)
  4079.         RETURN (1)
  4080.     END
  4081.     
  4082.     SELECT    @distribution_agent = NULL
  4083.     SELECT    @independent_agent_id = independent_agent, 
  4084.             @subscription_type_id = subscription_type,
  4085.             @distribution_agent = distribution_agent
  4086.         FROM  MSreplication_subscriptions
  4087.         WHERE UPPER(publisher) = UPPER(@publisher) AND
  4088.               publisher_db  = @publisher_db AND
  4089.               publication = @publication
  4090.     /* Distribution agent for push subscriptions is at distributor side */
  4091.     IF @subscription_type_id = 0
  4092.     BEGIN
  4093.         RAISERROR (21001, 16, -1)
  4094.         RETURN (1)
  4095.     END
  4096.  
  4097.     IF @distribution_agent IS NOT NULL
  4098.     BEGIN
  4099.         RAISERROR (21002, 11, -1, @distribution_agent)
  4100.         RETURN (1)
  4101.     END
  4102.  
  4103.     -- Parameter check: @subscriber_security_mode
  4104.     if @subscriber_security_mode is null
  4105.     begin
  4106.         if ( platform() & @platform_nt ) = @platform_nt
  4107.             select @subscriber_security_mode = 1
  4108.         else
  4109.             select @subscriber_security_mode = 0
  4110.     end    
  4111.  
  4112.     if ( ( platform() & @platform_nt ) <> @platform_nt and @subscriber_security_mode = 1 )
  4113.     begin
  4114.         RAISERROR(21038, 16, -1)
  4115.         RETURN (1)
  4116.     end
  4117.  
  4118.     if (@subscription_type_id <> 0)
  4119.     begin
  4120.         if (@subscriber_security_mode = 0) and (@subscriber_login IS NULL or rtrim(@subscriber_login) = '')
  4121.         begin
  4122.             raiserror(3217, 16, -1, '@subscriber_login')
  4123.             return (1)
  4124.         end
  4125.     end
  4126.     
  4127.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  4128.     begin
  4129.         raiserror(14027, 16, -1, 'The subscription properties table ''MSsubscription_properties''')
  4130.         return (1)
  4131.     end
  4132.  
  4133.     /*
  4134.     ** Construct unique name
  4135.     */
  4136.     if @subscriber is NULL select @subscriber = ''
  4137.     if @subscriber_db is NULL select @subscriber_db = ''
  4138.     SELECT @name = CONVERT(nvarchar(23),@publisher ) + '-' + CONVERT(nvarchar(23),@publisher_db) + '-' + 
  4139.                         CONVERT(nvarchar(23),@publication) + '-' + CONVERT(nvarchar(23),@subscriber) + '-' +
  4140.                         CONVERT(nvarchar(23),@subscriber_db) + '- 0'
  4141.  
  4142.     BEGIN TRAN
  4143.  
  4144.     /*
  4145.     ** If the publication is independent agent type or it is the first
  4146.     ** subscription on the non independent agent publications.
  4147.     */
  4148.  
  4149.     IF @independent_agent_id = 1 OR 
  4150.         NOT EXISTS (SELECT * FROM MSreplication_subscriptions WHERE
  4151.                              UPPER(@publisher) = UPPER(publisher) and
  4152.                             @publisher_db = publisher_db and
  4153.                             agent_id IS NOT NULL and
  4154.                             independent_agent = 0)
  4155.     BEGIN
  4156.         
  4157.         /* Construct agent command */
  4158.         SELECT @command = '-Publisher ' + @publisher + ' '
  4159.         SELECT @command = @command + '-PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  4160.         IF @independent_agent_id = 1
  4161.             SELECT @command = @command + '-Publication ' + QUOTENAME(@publication) + ' '
  4162.  
  4163.         SELECT @command = @command + '-Distributor ' + QUOTENAME(@distributor)  + ' '
  4164.  
  4165.         /*
  4166.         Use -Xdatabase to save command line space
  4167.         We can not use -Xserver for distribution because SQLExec will valid the server
  4168.         to be in sysservers.
  4169.  
  4170.         SELECT @command = @command + '-DistributionDB ' + QUOTENAME(@distribution_db)  + ' '
  4171.         */
  4172.         
  4173.         SELECT @command = @command + '-SubscriptionType ' + convert(nvarchar(10),@subscription_type_id)  + ' '
  4174.         SELECT @command = @command + '-Subscriber ' + QUOTENAME(@subscriber)  + ' '
  4175.     
  4176.         select @command = @command + '-SubscriberSecurityMode ' + 
  4177.             convert(nvarchar(10),@subscriber_security_mode) + ' '
  4178.         if @subscriber_login is not NULL
  4179.             select @command = @command + '-SubscriberLogin ' + quotename(@subscriber_login) + ' '
  4180.         if @subscriber_password is not NULL
  4181.         begin
  4182.             set @subscriber_enc_password = @subscriber_password
  4183.             exec @retcode = master.dbo.xp_repl_encrypt @subscriber_enc_password OUTPUT
  4184.             select @command = @command + '-SubscriberEncryptedPassword ' + quotename(@subscriber_enc_password) + ' '
  4185.         end
  4186.  
  4187.         SELECT @command = @command + '-SubscriberDB ' + QUOTENAME(@subscriber_db) + ' '
  4188.  
  4189.         /* 
  4190.         ** make sure the command line is not truncated
  4191.         */
  4192.         /* Use datalength because len doesn't count the last space in @command */
  4193.         IF (datalength(@command) + datalength(@optional_command_line)) > 8000
  4194.         BEGIN
  4195.             RAISERROR(20018, 16, -1)
  4196.             RETURN(1)
  4197.         END
  4198.  
  4199.         SELECT @command = @command + @optional_command_line
  4200.  
  4201.         -- Get Distribution category name (assumes category_id = 10)
  4202.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 10
  4203.  
  4204.         EXEC @retcode = dbo.sp_MSadd_repl_job
  4205.                    @name = @name,
  4206.                 @subsystem = 'Distribution',
  4207.                   @server = @@SERVERNAME,
  4208.                    @databasename = @distribution_db,
  4209.                 @enabled = 1,
  4210.                @freqtype = @frequency_type,
  4211.                @freqinterval = @frequency_interval,
  4212.                @freqsubtype = @frequency_subday,
  4213.                @freqsubinterval = @frequency_subday_interval,
  4214.                @freqrelativeinterval = @frequency_relative_interval,
  4215.                @freqrecurrencefactor = @frequency_recurrence_factor,
  4216.                @activestartdate = @active_start_date,
  4217.                @activeenddate = @active_end_date,
  4218.                @activestarttimeofday = @active_start_time_of_day,
  4219.                @activeendtimeofday = @active_end_time_of_day,
  4220.                 @command = @command,
  4221.                 @category_name = @category_name,
  4222.                 @retryattempts = 10,
  4223.                 @retrydelay = 1,
  4224.                 @job_id = @distribution_jobid OUTPUT
  4225.  
  4226.         IF @@ERROR <> 0 or @retcode <> 0
  4227.         BEGIN
  4228.             IF @@TRANCOUNT = 1
  4229.                 ROLLBACK TRAN
  4230.             ELSE
  4231.                 COMMIT TRAN   
  4232.             RETURN(1)
  4233.         END
  4234.     END
  4235.  
  4236.     if (@subscription_type_id = 1) OR (@subscription_type_id = 2)
  4237.     BEGIN
  4238.         IF NOT EXISTS (select * from MSsubscription_properties 
  4239.             where UPPER(publisher) = UPPER(@publisher)
  4240.               and publisher_db =  @publisher_db
  4241.               and publication = @publication) 
  4242.         BEGIN
  4243.             -- 0  transactional
  4244.             -- 1  snapshot
  4245.             -- 2  merge
  4246.             IF (@encrypted_distributor_password = 0)
  4247.             -- Encrypt the password
  4248.             BEGIN
  4249.                 EXEC @retcode = master.dbo.xp_repl_encrypt @distributor_password OUTPUT
  4250.                 IF @@error <> 0 OR @retcode <> 0
  4251.                     return 1
  4252.             END
  4253.     
  4254.             INSERT INTO MSsubscription_properties 
  4255.             (publisher, publisher_db, publication, publication_type, 
  4256.              publisher_login,publisher_password, publisher_security_mode, 
  4257.              distributor, distributor_login, distributor_password, 
  4258.              distributor_security_mode, ftp_address, ftp_port, ftp_login, 
  4259.              ftp_password)
  4260.             values (@publisher, @publisher_db, @publication, 0,    NULL, NULL, 1, 
  4261.                 @distributor, @distributor_login, @distributor_password, 
  4262.                 @distributor_security_mode, @ftp_address, @ftp_port, @ftp_login,
  4263.                 @ftp_password)
  4264.             IF @@ERROR <> 0 
  4265.             BEGIN
  4266.                 IF @@TRANCOUNT = 1
  4267.                     ROLLBACK TRAN
  4268.                 ELSE
  4269.                     COMMIT TRAN           
  4270.                 RETURN(1)
  4271.             END
  4272.         END
  4273.         ELSE
  4274.         BEGIN
  4275.             update MSsubscription_properties set
  4276.                 distributor = @distributor,
  4277.                 distributor_login = @distributor_login,
  4278.                 distributor_password = @distributor_password,
  4279.                 distributor_security_mode = @distributor_security_mode
  4280.                 where UPPER(publisher) = UPPER(@publisher)
  4281.                     and publisher_db =  @publisher_db
  4282.                     and publication = @publication
  4283.         END
  4284.         IF @@ERROR <> 0 
  4285.         BEGIN
  4286.             IF @@TRANCOUNT = 1
  4287.                 ROLLBACK TRAN
  4288.             ELSE
  4289.                 COMMIT TRAN           
  4290.             RETURN(1)
  4291.         END
  4292.     END
  4293.  
  4294.  
  4295.     /* If we do not have independent agents , i.e. independent_agent=0, but there is
  4296.     already a row for that publisher and that publisher database with a NOT null 
  4297.     distribution_agent_id, then set the @distribution_jobid to that id.  Note that if
  4298.     there are no rows returned, the value of the variable does not change, which is what we want.
  4299.     There should never be more than one row ever returned for this query - but will use TOP 1
  4300.     to insist that is the case.
  4301.     */
  4302.  
  4303.     SELECT DISTINCT @distribution_jobid=agent_id FROM MSreplication_subscriptions
  4304.     WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db =  @publisher_db
  4305.     AND agent_id IS NOT NULL AND independent_agent=0
  4306.     
  4307.     UPDATE MSreplication_subscriptions SET distribution_agent = @name,
  4308.         agent_id = @distribution_jobid
  4309.         WHERE UPPER(publisher) = UPPER(@publisher) AND 
  4310.             publisher_db =  @publisher_db AND 
  4311.             publication =  @publication AND 
  4312.             (subscription_type = 1 /* pull*/ OR subscription_type = 2) /*anonymous*/
  4313.  
  4314.     IF @@ERROR <> 0 
  4315.     BEGIN
  4316.         IF @@TRANCOUNT = 1
  4317.             ROLLBACK TRAN
  4318.         ELSE
  4319.             COMMIT TRAN           
  4320.         RETURN(1)
  4321.     END
  4322.  
  4323.     /* Conditional support for MobileSync */
  4324.     if LOWER(@enabled_for_syncmgr) = 'true'
  4325.     BEGIN
  4326.         /* Call sp_MSregistersubscription so that the subscription can be synchronized via MobileSync etc. */
  4327.         declare @subscription_id uniqueidentifier
  4328.         set @subscription_id = convert(uniqueidentifier, @distribution_jobid)
  4329.  
  4330.         exec @retcode = dbo.sp_MSregistersubscription @replication_type = 1,
  4331.                                     @publisher = @publisher,
  4332.                                     @publisher_db = @publisher_db,
  4333.                                     @publication = @publication,
  4334.                                     @subscriber = @subscriber,
  4335.                                     @subscriber_db = @subscriber_db,
  4336.                                     @subscriber_security_mode = @subscriber_security_mode,
  4337.                                     @subscriber_login = @subscriber_login,
  4338.                                     @subscriber_password = @subscriber_password,
  4339.                                     @distributor = @distributor,
  4340.                                     @subscription_id = @subscription_id,
  4341.                                     @independent_agent = @independent_agent_id,
  4342.                                     @subscription_type = @subscription_type_id
  4343.         IF @@ERROR <> 0 or @retcode <> 0
  4344.         BEGIN
  4345.             IF @@TRANCOUNT = 1
  4346.                 ROLLBACK TRAN
  4347.             ELSE
  4348.                 COMMIT TRAN           
  4349.             RETURN(1)
  4350.         END
  4351.     END
  4352.  
  4353.     COMMIT TRAN
  4354.     RETURN(0)
  4355. GO
  4356.  
  4357.  
  4358. raiserror('Creating procedure sp_helpsubscription_properties', 0,1)
  4359. go
  4360. CREATE PROCEDURE sp_helpsubscription_properties
  4361.         @publisher sysname = '%', 
  4362.         @publisher_db sysname = '%', 
  4363.         @publication sysname = '%', 
  4364.         @publication_type int = NULL
  4365.     AS
  4366.  
  4367.     SET NOCOUNT ON
  4368.  
  4369.     declare @retcode int
  4370.  
  4371.     /*
  4372.     ** Security Check
  4373.     */
  4374.  
  4375.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  4376.     IF @@ERROR <> 0 or @retcode <> 0
  4377.         RETURN(1)
  4378.  
  4379.     /*
  4380.     ** The logic is added here for the case where MSsubscription_properties table does not exist
  4381.     ** or relevant entry is not added because sp_addmergepullsubscription_agent or sp_addsubscription_agent
  4382.     ** is not called.
  4383.     */
  4384.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  4385.     begin
  4386.         return (0)
  4387.     end
  4388.  
  4389.     IF (@publication IS NULL) OR (@publication = '')
  4390.         select @publication = '%'
  4391.  
  4392.     IF @publication_type IS NULL
  4393.     BEGIN
  4394.         select publisher, publisher_db, publication, publication_type, publisher_login,
  4395.             publisher_password, publisher_security_mode, distributor, distributor_login,
  4396.             distributor_password, distributor_security_mode, ftp_address, isnull(ftp_port, 0),
  4397.             ftp_login, ftp_password
  4398.          from MSsubscription_properties
  4399.             where ((@publisher = N'%') or (UPPER(publisher) = UPPER(@publisher)))
  4400.             and publisher_db like @publisher_db
  4401.             and publication like @publication
  4402.     END
  4403.     ELSE
  4404.     BEGIN
  4405.         select publisher, publisher_db, publication, publication_type, publisher_login,
  4406.             publisher_password, publisher_security_mode, distributor, distributor_login,
  4407.             distributor_password, distributor_security_mode, ftp_address, isnull(ftp_port, 0),
  4408.             ftp_login, ftp_password
  4409.         from MSsubscription_properties
  4410.             where ((@publisher = N'%') or (UPPER(publisher) = UPPER(@publisher)))
  4411.             and publisher_db like @publisher_db
  4412.             and publication like @publication
  4413.             and publication_type = @publication_type
  4414.     END    
  4415.  
  4416.     return (0)
  4417. GO
  4418.  
  4419. EXEC dbo.sp_MS_marksystemobject sp_helpsubscription_properties
  4420. GO
  4421.  
  4422. raiserror('Creating procedure sp_change_subscription_properties', 0,1)
  4423. go
  4424. CREATE PROCEDURE sp_change_subscription_properties
  4425.         @publisher sysname, 
  4426.         @publisher_db sysname, 
  4427.         @publication sysname, 
  4428.         @property sysname,
  4429.         @value sysname
  4430.     AS
  4431.  
  4432.     SET NOCOUNT ON
  4433.  
  4434.     DECLARE @command nvarchar(2000)
  4435.     DECLARE @column_to_update nvarchar(64)
  4436.     DECLARE @value_string nvarchar(255)
  4437.     DECLARE @retcode int
  4438.  
  4439.     /*
  4440.     ** Security Check
  4441.     */
  4442.  
  4443.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  4444.     IF @@ERROR <> 0 or @retcode <> 0
  4445.         RETURN(1)
  4446.  
  4447.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  4448.     begin
  4449.         raiserror(14027, 16, -1, 'The subscription properties table ''MSsubscription_properties''')
  4450.         return (1)
  4451.     end
  4452.     
  4453.     if (@publisher is null)
  4454.     begin
  4455.         raiserror(14043, 16, -1, '@publisher')
  4456.         return (1)
  4457.     end
  4458.  
  4459.     if(@publisher_db is null)
  4460.     begin
  4461.         raiserror(14043, 16, -1, '@publisher_db')
  4462.         return (1)
  4463.     end
  4464.     
  4465.     IF (@property IS NULL)
  4466.     begin
  4467.         raiserror(14043, 16, -1, '@property')
  4468.         return (1)
  4469.     end
  4470.     ELSE IF (lower(@property) = 'publisher_login')
  4471.         select @column_to_update = 'publisher_login'
  4472.     ELSE IF (lower(@property) = 'publisher_password')
  4473.     begin
  4474.         select @column_to_update = 'publisher_password'
  4475.         EXEC @retcode = master.dbo.xp_repl_encrypt @value OUTPUT
  4476.         IF @@error <> 0 OR @retcode <> 0
  4477.             return 1
  4478.     end
  4479.     ELSE IF (lower(@property) = 'publisher_security_mode')
  4480.         select @column_to_update = 'publisher_security_mode'
  4481.     ELSE IF (lower(@property) = 'distributor')
  4482.         select @column_to_update = 'distributor'
  4483.     ELSE IF (lower(@property) = 'distributor_login')
  4484.         select @column_to_update = 'distributor_login'
  4485.     ELSE IF (lower(@property) = 'distributor_password')
  4486.     begin
  4487.         select @column_to_update = 'distributor_password'
  4488.         EXEC @retcode = master.dbo.xp_repl_encrypt @value OUTPUT
  4489.         IF @@error <> 0 OR @retcode <> 0
  4490.             return 1
  4491.     end
  4492.     ELSE IF (lower(@property) = 'distributor_security_mode')
  4493.         select @column_to_update = 'distributor_security_mode'
  4494.     ELSE IF (lower(@property) = 'ftp_address')
  4495.         select @column_to_update = 'ftp_address'
  4496.     ELSE IF (lower(@property) = 'ftp_port')
  4497.         select @column_to_update = 'ftp_port'
  4498.     ELSE IF (lower(@property) = 'ftp_login')
  4499.         select @column_to_update = 'ftp_login'
  4500.     ELSE IF (lower(@property) = 'ftp_password')
  4501.         select @column_to_update = 'ftp_password'
  4502.     ELSE
  4503.     BEGIN
  4504.         raiserror (3217, 16, -1, '@property')
  4505.         return(1)
  4506.     END
  4507.  
  4508.  
  4509.  
  4510.     IF (lower(@property) = 'distributor_security_mode') OR (lower(@property) = 'publisher_security_mode') 
  4511.     BEGIN
  4512.         IF NOT ( @value = 0 or @value = 1 or (@value = 2 and lower(@property) = 'publisher_security_mode' )) 
  4513.         BEGIN
  4514.             raiserror(3217, 16, -1, '@value')
  4515.             return(1)
  4516.         END
  4517.         select @value_string = convert(nvarchar(1), @value)
  4518.     END
  4519.     ELSE
  4520.     BEGIN
  4521.         IF (@value IS NULL)
  4522.             select @value_string = 'NULL'
  4523.         ELSE
  4524.             select @value_string = 'N''' + rtrim(@value) + ''''
  4525.     END
  4526.  
  4527.     if (@publication is null) or (@publication = '')
  4528.     begin
  4529.         select @publication = '%'
  4530.     end
  4531.     
  4532.     -- Password is encrypted. Cannot use dynamic query (exec (@cmd)) to update
  4533.     -- otherwise, the chars will be convert to '???'
  4534.     IF (lower(@property) = 'distributor_password')
  4535.     begin
  4536.         update MSsubscription_properties set distributor_password = @value where 
  4537.             UPPER(publisher) = UPPER(@publisher) and 
  4538.             publisher_db = @publisher_db and
  4539.             publication like @publication 
  4540.     end
  4541.     ELSE IF (lower(@property) = 'publisher_password')
  4542.     begin
  4543.         update MSsubscription_properties set publisher_password = @value where 
  4544.             UPPER(publisher) = UPPER(@publisher) and 
  4545.             publisher_db = @publisher_db and
  4546.             publication like @publication 
  4547.     end
  4548.     else
  4549.     begin
  4550.         select @command = N'update MSsubscription_properties set ' + @column_to_update + '= ' + @value_string
  4551.                 + ' where UPPER(publisher) = UPPER(''' + @publisher 
  4552.                 + ''') and publisher_db = ''' + @publisher_db
  4553.                 + ''' and publication like ''' + @publication + ''''
  4554.         EXEC (@command)
  4555.     end
  4556.         
  4557.     if @@error <> 0
  4558.         return (1)
  4559.     else
  4560.         return (0)
  4561.  
  4562. GO
  4563. EXEC dbo.sp_MS_marksystemobject sp_change_subscription_properties
  4564. GO
  4565. grant execute on dbo.sp_change_subscription_properties to public
  4566.  
  4567. raiserror('Creating procedure sp_MSget_pullsubsagent_owner', 0,1)
  4568. go
  4569.  
  4570. CREATE PROCEDURE sp_MSget_pullsubsagent_owner (
  4571.     @publisher    sysname,
  4572.     @publisher_db sysname,
  4573.     @publication  sysname,   /* publication name */
  4574.     @owner_sid    varbinary(85) OUTPUT 
  4575.     ) AS
  4576.  
  4577.     declare @job_id uniqueidentifier
  4578.     set nocount on
  4579.  
  4580.     select @owner_sid = null
  4581.         
  4582.  
  4583.     if exists (select * from sysobjects 
  4584.                where type = 'U' and 
  4585.                      name = 'MSreplication_subscriptions')
  4586.     begin 
  4587.         -- Get the job_id corresponding to the publication
  4588.         select @job_id = agent_id
  4589.         from MSreplication_subscriptions
  4590.         where upper(@publisher) = upper(publisher) and
  4591.             @publisher_db = publisher_db and
  4592.             @publication = publication 
  4593.  
  4594.         -- Using the job_id in MSsubscription properties to get the owner_sid 
  4595.         -- in msdb..sysjobs    
  4596.         select @owner_sid = owner_sid
  4597.         from  msdb..sysjobs
  4598.         where @job_id = job_id
  4599.     end            
  4600. go 
  4601.  
  4602. exec dbo.sp_MS_marksystemobject 'sp_MSget_pullsubsagent_owner'
  4603.  
  4604. raiserror('Creating procedure sp_droppullsubscription', 0,1)
  4605. go
  4606.  
  4607. CREATE PROCEDURE sp_droppullsubscription (
  4608.     @publisher sysname,
  4609.     @publisher_db sysname,
  4610.     @publication sysname,   /* publication name */
  4611.     @reserved bit = 0
  4612.     ) AS
  4613.  
  4614.     SET NOCOUNT ON
  4615.  
  4616.     /*
  4617.     ** Declarations.
  4618.     */
  4619.  
  4620.  
  4621.     DECLARE @name nvarchar(255)
  4622.     DECLARE @retcode int
  4623.     DECLARE @agent_id binary(16)
  4624.     DECLARE @publisher_ex sysname          /* Expression used in the cursor */
  4625.     DECLARE @publisher_db_ex sysname     /* Expression used in the cursor */
  4626.     DECLARE @publication_ex sysname      /* Expression used in the cursor */
  4627.     DECLARE @expanded bit
  4628.     DECLARE @subscription_type_id int
  4629.     DECLARE @count_sub int
  4630.     DECLARE @drop_null_pub bit
  4631.     DECLARE @drop_push_bit bit
  4632.     DECLARE @push int
  4633.     DECLARE @implicit_transaction int
  4634.     DECLARE @close_cursor_at_commit int
  4635.     DECLARE @owner_sid varbinary(85)
  4636.     DECLARE @owner_name sysname
  4637.     DECLARE @qualified_publication_name nvarchar(512)
  4638.     
  4639.     /* 
  4640.     ** Initialization
  4641.     */
  4642.     SELECT @expanded = 0
  4643.     SELECT @drop_null_pub = 0
  4644.     SELECT @push = 0
  4645.  
  4646.     /*
  4647.     ** Get the original set value off IMPLICIT_TRANSACTIONS and CURSOR_CLOSE_ON_COMMIT
  4648.     **      before set these two to off
  4649.     */
  4650.     select @implicit_transaction = 0
  4651.     select @close_cursor_at_commit = 0
  4652.     IF (@reserved = 0)
  4653.     BEGIN
  4654.         SELECT @implicit_transaction = @@options & 2
  4655.         SELECT @close_cursor_at_commit = @@options & 4
  4656.         SET IMPLICIT_TRANSACTIONS OFF
  4657.         SET CURSOR_CLOSE_ON_COMMIT OFF
  4658.     END
  4659.  
  4660.     /*
  4661.     ** Security Check
  4662.     */
  4663.  
  4664.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  4665.     IF @@ERROR <> 0 or @retcode <> 0
  4666.         RETURN(1)
  4667.  
  4668.     SELECT @drop_push_bit = 0    
  4669.     
  4670.     /*
  4671.     ** Check parameter and set expressions used by cursor
  4672.     */
  4673.     
  4674.     /* Publisher */
  4675.     IF @publisher IS NULL
  4676.     BEGIN
  4677.         RAISERROR (14043, 16, -1, '@publisher')
  4678.         RETURN (1)
  4679.     END
  4680.  
  4681.     IF @publisher = 'all'
  4682.     BEGIN
  4683.         SELECT @publisher_ex = '%'
  4684.         SELECT @expanded = 1
  4685.     END
  4686.     ELSE
  4687.     BEGIN
  4688.         EXECUTE @retcode = dbo.sp_validname @publisher
  4689.         IF @retcode <> 0
  4690.         RETURN (1)
  4691.         SELECT @publisher_ex = @publisher
  4692.     END
  4693.  
  4694.  
  4695.     /* Publisher_db */
  4696.     IF @publisher_db IS NULL
  4697.     BEGIN
  4698.             RAISERROR (14043, 16, -1, '@publisher_db')
  4699.             RETURN (1)
  4700.     END
  4701.  
  4702.     IF @publisher_db = 'all'
  4703.     BEGIN
  4704.         SELECT @publisher_db_ex = '%'
  4705.         select @expanded = 1
  4706.     END
  4707.     ELSE
  4708.     BEGIN
  4709.         /*
  4710.         EXECUTE @retcode = dbo.sp_validname @publisher_db
  4711.         IF @retcode <> 0
  4712.         RETURN (1)
  4713.         */
  4714.         SELECT @publisher_db_ex = @publisher_db
  4715.     END
  4716.  
  4717.     /* 
  4718.     ** Publication
  4719.     ** '' is not a valid name but it may be in the publication name in the table. 
  4720.     */
  4721.     IF @publication IS NULL OR @publication = ''
  4722.     BEGIN
  4723.         SELECT @drop_null_pub = 1
  4724.     END
  4725.     ELSE IF @publication = 'all'
  4726.     BEGIN
  4727.         SELECT @publication_ex = '%'
  4728.         SELECT @expanded = 1
  4729.         SELECT @drop_null_pub = 1
  4730.     END
  4731.     ELSE
  4732.     BEGIN
  4733.         EXECUTE @retcode = dbo.sp_validname @publication
  4734.         IF @retcode <> 0
  4735.         RETURN (1)
  4736.         SELECT @publication_ex = @publication
  4737.     END
  4738.  
  4739.     /*
  4740.     ** Check to see if the  subscription table exists
  4741.     */
  4742.     IF NOT EXISTS (SELECT * FROM sysobjects 
  4743.                 WHERE type = 'U' AND
  4744.                       name = 'MSreplication_subscriptions')
  4745.     BEGIN
  4746.         IF @expanded = 0
  4747.         BEGIN
  4748.             RAISERROR(14135, 11, -1,  @publisher, 
  4749.                 @publisher_db, @publication)
  4750.             RETURN(1)
  4751.         END
  4752.         ELSE
  4753.             RETURN(0)
  4754.     END
  4755.  
  4756.     IF @expanded = 0 
  4757.     BEGIN 
  4758.         /*
  4759.         **
  4760.         ** Check to see if the subscription entry exists
  4761.         */
  4762.         IF  NOT EXISTS (SELECT * FROM  MSreplication_subscriptions 
  4763.                     WHERE UPPER(publisher) = UPPER(@publisher) AND
  4764.                       publisher_db = @publisher_db AND
  4765.                       publication = @publication)     
  4766.         BEGIN
  4767.             RAISERROR(14135, 11, -1, @publisher, @publisher_db, @publication)
  4768.             RETURN(1)
  4769.         END
  4770.  
  4771.         /* 
  4772.         ** Make sure the subscription is not push type if @drop_push_bit = 0
  4773.         */
  4774.         IF @drop_push_bit = 0
  4775.         BEGIN
  4776.             IF EXISTS (SELECT * FROM MSreplication_subscriptions 
  4777.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  4778.                   publisher_db = @publisher_db AND
  4779.                   publication = @publication AND
  4780.                   subscription_type = @push AND
  4781.                   @drop_push_bit = 0)
  4782.             BEGIN
  4783.                 RAISERROR(20017, 16, -1)
  4784.                 RETURN(1)
  4785.             END
  4786.         END
  4787.  
  4788.     END
  4789.     ELSE
  4790.     /* 
  4791.     ** Open a cursor and call recursively if
  4792.     ** parameters are expanded.
  4793.     */
  4794.     BEGIN
  4795.  
  4796.         /*        
  4797.         **  Note: Any expression check on null value is false
  4798.         ** @subscription_type_id is NULL <==> push
  4799.         ** @subscription_type_id is NOT NULL <==> non push
  4800.         */
  4801.         DECLARE hCdroppullsubscription CURSOR LOCAL FAST_FORWARD FOR
  4802.             SELECT DISTINCT publisher, publisher_db, publication    
  4803.                 FROM MSreplication_subscriptions
  4804.                 WHERE ((@publisher_ex = N'%') OR (UPPER(publisher) = UPPER(@publisher_ex))) AND
  4805.                       publisher_db LIKE @publisher_db_ex AND
  4806.                       (publication LIKE @publication_ex OR
  4807.                       (@drop_null_pub = 1 AND
  4808.                       publication IS NULL)) AND
  4809.                       ((@drop_push_bit =0 AND
  4810.                       subscription_type <> @push) OR
  4811.                       @drop_push_bit = 1)
  4812.         FOR READ ONLY
  4813.         OPEN hCdroppullsubscription
  4814.  
  4815.         FETCH hCdroppullsubscription INTO @publisher, 
  4816.             @publisher_db, @publication
  4817.         WHILE (@@fetch_status <> -1)
  4818.         BEGIN
  4819.             EXECUTE @retcode  = dbo.sp_droppullsubscription @publisher = @publisher, 
  4820.                 @publisher_db = @publisher_db, @publication = @publication, 
  4821.                 @reserved = 1
  4822.  
  4823.             FETCH hCdroppullsubscription INTO @publisher, 
  4824.                 @publisher_db, @publication
  4825.         END
  4826.  
  4827.         CLOSE hCdroppullsubscription
  4828.         DEALLOCATE hCdroppullsubscription
  4829.         RETURN (0)
  4830.     END
  4831.     
  4832.     /*
  4833.     ** Only members of the sysadmin group and the creator of the distribution
  4834.     ** agent can drop a pull subscription successfully. This behavior matches 
  4835.     ** the behavior of the sysjobs_view. DBO of the subscriber database, 
  4836.     ** sysadmins (owner is undefined) can drop a subscription if the owner_sid 
  4837.     ** is null.
  4838.     */
  4839.  
  4840.     EXEC sp_MSget_pullsubsagent_owner @publisher = @publisher,
  4841.                                       @publisher_db = @publisher_db,
  4842.                                       @publication = @publication,
  4843.                                       @owner_sid = @owner_sid OUTPUT
  4844.  
  4845.     IF (@owner_sid is not null AND
  4846.         (SUSER_SID() <> @owner_sid) AND
  4847.         (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0))
  4848.     BEGIN
  4849.         SELECT @owner_name = SUSER_SNAME(@owner_sid)
  4850.         SELECT @qualified_publication_name = @publisher + N':' + 
  4851.                                              @publisher_db + N':' +
  4852.                                              @publication
  4853.         RAISERROR(21121,16,-1,@owner_name, @qualified_publication_name) 
  4854.         RETURN (1)
  4855.     END
  4856.  
  4857.     /* 
  4858.     ** Get the agent name, it may be dropped later.
  4859.     */
  4860.     SELECT @agent_id = agent_id FROM MSreplication_subscriptions
  4861.                     WHERE UPPER(publisher) = UPPER(@publisher) AND
  4862.                           publisher_db  = @publisher_db AND
  4863.                           publication = @publication 
  4864.  
  4865.     -- If the agent is used by other subscription, don't drop it.
  4866.     if (select count(*) from MSreplication_subscriptions where
  4867.         agent_id = @agent_id) > 1
  4868.         select @agent_id = NULL
  4869.  
  4870.     begin tran
  4871.     save TRAN droppullsubscription
  4872.  
  4873.     /*
  4874.     ** Drop the subscription entry and the distribution agent if it exists 
  4875.     */
  4876.  
  4877.  
  4878.     /* 
  4879.     ** If the distribution agent is not used anymore,
  4880.     ** drop the agent if it exists
  4881.     */
  4882.  
  4883.     IF @agent_id IS NOT NULL
  4884.     BEGIN
  4885.         IF (EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @agent_id))
  4886.         BEGIN
  4887.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @agent_id
  4888.              IF @@ERROR <> 0 or @retcode <> 0
  4889.                 GOTO UNDO
  4890.  
  4891.             -- Delete MSreplication_subsciptions table after dropping 
  4892.             -- the distribution agent and delay one second
  4893.             -- to avoid deadlock with it.
  4894.             WAITFOR DELAY '00:00:01'
  4895.         END
  4896.  
  4897.     END
  4898.  
  4899.     /* Call sp_MSunregistersubscription so that the reg entries get deleted */
  4900.     declare @subscriber_db sysname
  4901.     set @subscriber_db = DB_NAME()
  4902.     exec @retcode = dbo.sp_MSunregistersubscription @publisher = @publisher,
  4903.                                 @publisher_db = @publisher_db,
  4904.                                 @publication = @publication,
  4905.                                 @subscriber = @@SERVERNAME,
  4906.                                 @subscriber_db = @subscriber_db
  4907.  
  4908.     IF @retcode<>0 or @@ERROR<>0
  4909.         GOTO UNDO
  4910.     /*
  4911.     -- Delete MSreplication_subsciptions table after dropping the distribution agent\
  4912.     -- To avoid deadlock with it.
  4913.     --DELETE MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher)    AND
  4914.         --publisher_db  = @publisher_db AND
  4915.         --publication = @publication 
  4916.     
  4917.     --IF @@ERROR <> 0 
  4918.     --    GOTO UNDO
  4919.  
  4920.     */
  4921.  
  4922.     IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties')
  4923.     BEGIN
  4924.         DELETE FROM MSsubscription_properties 
  4925.         WHERE UPPER(publisher) = UPPER(@publisher)    AND
  4926.         publisher_db  = @publisher_db AND
  4927.         publication = @publication 
  4928.  
  4929.         IF @@ERROR <> 0 
  4930.             GOTO UNDO
  4931.  
  4932.         IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  4933.         BEGIN
  4934.             DROP TABLE MSsubscription_properties
  4935.             IF @@ERROR <> 0 
  4936.                 GOTO UNDO
  4937.         END
  4938.     END
  4939.     
  4940.     /*
  4941.     ** Clean up metadata at subscriber side
  4942.     */
  4943.     exec @retcode = dbo.sp_subscription_cleanup @publisher = @publisher,
  4944.                                             @publisher_db  = @publisher_db,
  4945.                                             @publication = @publication
  4946.     IF @retcode<>0 or @@ERROR<>0
  4947.         GOTO UNDO
  4948.  
  4949.     --
  4950.     -- drop table MSreplication_subscriptions if empty and
  4951.     -- not in recursive call
  4952.     --
  4953.     IF (@reserved = 0 AND 
  4954.         NOT EXISTS (SELECT * FROM MSreplication_subscriptions))
  4955.     BEGIN
  4956.         DROP TABLE MSreplication_subscriptions
  4957.         IF @@ERROR <> 0 
  4958.             GOTO UNDO
  4959.     END
  4960.     
  4961.  
  4962.     COMMIT TRAN
  4963.     /*
  4964.     ** set back the two settings if needed 
  4965.     */
  4966.     if @reserved = 0
  4967.     BEGIN
  4968.         IF @implicit_transaction <>0 
  4969.             SET IMPLICIT_TRANSACTIONS ON
  4970.         IF @close_cursor_at_commit <>0 
  4971.             SET CURSOR_CLOSE_ON_COMMIT ON
  4972.     END
  4973.     RETURN (0)
  4974.  
  4975. UNDO:
  4976.     IF @@TRANCOUNT > 0
  4977.     begin
  4978.         ROLLBACK TRAN droppullsubscription
  4979.         COMMIT TRAN   
  4980.     end
  4981.     /*
  4982.     ** set back the two settings if needed
  4983.     */
  4984.     if @reserved = 0
  4985.     BEGIN
  4986.         IF @implicit_transaction <>0 
  4987.             SET IMPLICIT_TRANSACTIONS ON
  4988.         IF @close_cursor_at_commit <>0 
  4989.             SET CURSOR_CLOSE_ON_COMMIT ON
  4990.     END
  4991.  
  4992.     return 1
  4993. go
  4994.  
  4995.  
  4996. raiserror('Creating procedure sp_helppullsubscription', 0,1, 0,1)
  4997. go
  4998.  
  4999. CREATE PROCEDURE sp_helppullsubscription (
  5000.     @publisher sysname = '%',
  5001.     @publisher_db sysname = '%',
  5002.     @publication sysname = '%',
  5003.     @show_push nvarchar(5) = 'false'
  5004.     ) AS
  5005.  
  5006.     SET NOCOUNT ON
  5007.  
  5008.     /*
  5009.     ** Declarations.
  5010.     */
  5011.  
  5012.  
  5013.     DECLARE @command nvarchar(255)
  5014.     DECLARE @name nvarchar(255)
  5015.     DECLARE @retcode int
  5016.     DECLARE @show_push_bit bit
  5017.     DECLARE @push int
  5018.     declare @subscriber            sysname
  5019.     declare @subscriber_db        sysname
  5020.     declare @publisher_local    sysname
  5021.     declare @publisher_db_local    sysname
  5022.     declare @publication_local    sysname
  5023.     declare @subscription_name     nvarchar(1000)
  5024.     declare @regkey                nvarchar(1000)
  5025.     declare @syncmgr_keyexist                int
  5026.     declare @helpsubscriptioncursor_open    int
  5027.  
  5028.  
  5029.     SELECT @push = 0
  5030.  
  5031.     /*
  5032.     ** Security Check
  5033.     */
  5034.  
  5035.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  5036.     IF @@ERROR <> 0 or @retcode <> 0
  5037.         RETURN(1)
  5038.  
  5039.     /*
  5040.     ** Initializations.
  5041.     */
  5042.     set @subscriber = @@SERVERNAME     
  5043.     set @subscriber_db = DB_NAME()
  5044.  
  5045.     /*
  5046.     ** Parameter Check: @publisher
  5047.     ** Check to make sure that the publisher is define
  5048.     */
  5049.     IF @publisher IS NULL
  5050.     BEGIN
  5051.         RAISERROR (14043, 16, -1, '@publisher')
  5052.         RETURN (1)
  5053.     END
  5054.  
  5055.     IF @publisher <> '%' 
  5056.     BEGIN
  5057.         EXECUTE @retcode = dbo.sp_validname @publisher
  5058.  
  5059.         IF @@ERROR <> 0 OR @retcode <> 0
  5060.                RETURN (1)
  5061.     END
  5062.  
  5063.     IF @publication <> '%' 
  5064.     BEGIN
  5065.         EXECUTE @retcode = dbo.sp_validname @publication
  5066.  
  5067.         IF @@ERROR <> 0 OR @retcode <> 0
  5068.                RETURN (1)
  5069.     END
  5070.  
  5071.  
  5072.     IF @show_push IS NOT NULL AND 
  5073.         LOWER(@show_push) NOT IN ('true', 'false')
  5074.     BEGIN
  5075.         RAISERROR (14148, 16, -1, '@show_push')
  5076.         RETURN (1)
  5077.     END
  5078.  
  5079.     IF LOWER(@show_push) = 'false'                
  5080.         SELECT @show_push_bit = 0    
  5081.     IF LOWER(@show_push) = 'true'    
  5082.         SELECT @show_push_bit = 1
  5083.  
  5084.  
  5085.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  5086.         type = 'U' AND
  5087.         name = 'MSreplication_subscriptions')
  5088.         RETURN (0)
  5089.  
  5090.     create table #helpsubscription
  5091.                 (
  5092.                     publisher                 sysname     NOT NULL,
  5093.                     publisher_db             sysname     NOT NULL, 
  5094.                     publication             sysname     NULL, 
  5095.                     independent_agent         bit         NOT NULL,
  5096.                     subscription_type         int         NOT NULL,
  5097.                     distribution_agent         nvarchar(100) NULL, 
  5098.                     time                     smalldatetime NOT NULL,
  5099.                     description             nvarchar(255) NULL,
  5100.                     transaction_timestamp     varbinary(16) NOT NULL,
  5101.                     -- SyncTran
  5102.                     update_mode             tinyint     NOT NULL,
  5103.                     agent_id                 binary(16)     NULL,
  5104.                     subscription_guid         binary(16)     NULL,
  5105.                     subid                     binary(16)     NULL,
  5106.                     immediate_sync             bit         NOT NULL,
  5107.                     enabled_for_syncmgr        int            NULL            
  5108.                 )
  5109.                 
  5110.     insert into #helpsubscription
  5111.         select *, 0 from MSreplication_subscriptions
  5112.                 WHERE ((@publisher = N'%') OR (UPPER(publisher) = UPPER(@publisher))) AND
  5113.                       publisher_db  LIKE @publisher_db AND
  5114.                       publication LIKE @publication AND
  5115.                       (subscription_type <> @push OR
  5116.                        @show_push_bit = 1)
  5117.         ORDER BY publisher, publisher_db, publication
  5118.  
  5119.     declare #helpsubscriptioncursor CURSOR LOCAL FAST_FORWARD FOR 
  5120.         select DISTINCT publisher, publisher_db, publication
  5121.            FROM #helpsubscription
  5122.             FOR READ ONLY
  5123.     create table #syncmgr_keyexist (syncmgr_keyexist int)
  5124.     open #helpsubscriptioncursor
  5125.     select @helpsubscriptioncursor_open = 1                    
  5126.     fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local
  5127.     while (@@fetch_status <> -1)
  5128.         begin
  5129.             set @subscription_name = @publisher_local + ':' + @publisher_db_local + ':' + @publication_local + ':' + @subscriber + ':' + @subscriber_db
  5130.             /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  5131.             set @subscription_name = REPLACE(@subscription_name,'\','/')
  5132.             set @regkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\' + @subscription_name
  5133.             insert into #syncmgr_keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @regkey
  5134.             select @syncmgr_keyexist = syncmgr_keyexist from #syncmgr_keyexist
  5135.             update #helpsubscription set enabled_for_syncmgr = @syncmgr_keyexist 
  5136.                 where UPPER(publisher) = UPPER(@publisher_local)
  5137.                     and publisher_db = @publisher_db_local
  5138.                     and publication = @publication_local
  5139.                 
  5140.             fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local
  5141.         end
  5142.  
  5143.  
  5144.     /*
  5145.     ** Get the result
  5146.     **
  5147.     ** Note: have to return meta data
  5148.     */
  5149.     SELECT  'publisher'                = publisher,
  5150.             'publisher database'    = publisher_db,
  5151.             'publication'            = publication,
  5152.             'independent_agent'        = independent_agent,
  5153.             'subscription type'     = subscription_type,
  5154.             'distribution agent'    = distribution_agent,
  5155.             'publication description'   = description,
  5156.             'last updating time'        = convert(nvarchar(12), time, 112) + 
  5157.                                           substring(convert(nvarchar(24), time, 121), 11,13),
  5158.             'subscription_name'          = publisher + ':' + publisher_db + ':' + publication,
  5159.             'last transaction timestamp' = transaction_timestamp,
  5160.             -- SyncTran
  5161.             'update_mode'         = update_mode,
  5162.             'distribution agent job_id' = agent_id,
  5163.             'enabled for syncmgr' = enabled_for_syncmgr,
  5164.             'subscription guid' = subscription_guid,
  5165.             'subid ' = subid,
  5166.             'immediate_sync' = immediate_sync
  5167.         FROM #helpsubscription
  5168.  
  5169.     drop table #helpsubscription
  5170.     if (@helpsubscriptioncursor_open = 1)
  5171.         begin
  5172.             close #helpsubscriptioncursor
  5173.             deallocate #helpsubscriptioncursor
  5174.         end            
  5175.     drop table #syncmgr_keyexist    
  5176.             
  5177.         
  5178. GO
  5179.  
  5180.  
  5181. raiserror('Creating procedure sp_MStable_has_unique_index', 0,1)
  5182. go
  5183.  
  5184. create procedure sp_MStable_has_unique_index @tabid int
  5185. as
  5186. begin
  5187.  
  5188.     /* 
  5189.     ** Returns id of unique index, if it exists, else 0
  5190.     */
  5191.     declare @indid int
  5192.  
  5193.     if (ObjectProperty(@tabid, 'IsTable') = 1) and (ObjectProperty(@tabid, 'TableHasIndex') = 1)
  5194.     begin
  5195.         -- First get the primary index id. See bug 52471
  5196.         select @indid = i.indid from sysindexes i where 
  5197.             -- get the primary key index
  5198.             (i.status & 2048) <> 0
  5199.             and i.id = @tabid
  5200.  
  5201.         if @indid is null
  5202.         begin
  5203.             -- Get the first unique index
  5204.             select top 1 @indid = i.indid from sysindexes i where 
  5205.                 (i.status & 2) <> 0
  5206.                 and i.id = @tabid
  5207.                 order by i.indid asc
  5208.         end
  5209.         if @indid is null select @indid = 0
  5210.     end
  5211.     else
  5212.         select @indid = 0
  5213.  
  5214.     return @indid
  5215. end
  5216. go
  5217.  
  5218.  
  5219. raiserror('Creating procedure sp_MSchange_retention', 0,1)
  5220. GO
  5221.  
  5222. -- @value has to be unicode too.
  5223.  
  5224. CREATE PROCEDURE sp_MSchange_retention (@pubid uniqueidentifier, @value nvarchar(255))
  5225. as
  5226.     update sysmergepublications set retention = convert(int, @value) where pubid = @pubid
  5227. go
  5228. exec dbo.sp_MS_marksystemobject sp_MSchange_retention 
  5229. go
  5230. grant execute on dbo.sp_MSchange_retention to public
  5231.  
  5232.  
  5233. raiserror('Creating procedure sp_MSchange_priority', 0,1)
  5234. GO
  5235.  
  5236. -- @value has to be unicode too.
  5237.  
  5238. CREATE PROCEDURE sp_MSchange_priority (@subid uniqueidentifier, @value nvarchar(255))
  5239. as
  5240.     update sysmergesubscriptions set priority = convert(real, @value)
  5241.            where subid = @subid
  5242. go
  5243. exec dbo.sp_MS_marksystemobject sp_MSchange_priority 
  5244. go
  5245. grant execute on dbo.sp_MSchange_priority to public
  5246.  
  5247. raiserror('Creating procedure sp_expired_subscription_cleanup', 0,1)
  5248. GO
  5249.  
  5250. CREATE PROCEDURE sp_expired_subscription_cleanup
  5251. AS
  5252. declare @retcode         int
  5253. declare @publisher_db    sysname
  5254. declare @category        int
  5255. declare @proc_name        nvarchar(200)
  5256. declare @distributor     sysname
  5257. declare @distribdb        sysname
  5258. declare @distproc        nvarchar(270)
  5259. /*
  5260. ** Security Check
  5261. */
  5262.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  5263.     IF @@ERROR <> 0 or @retcode <> 0
  5264.         return (1)
  5265.     /*
  5266.     ** Get distribution server information for remote RPC call.
  5267.     */
  5268.  
  5269. EXECUTE @retcode = sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  5270.      @distribdb   = @distribdb OUTPUT
  5271. IF @@ERROR <> 0 or @retcode <> 0
  5272.     BEGIN
  5273.         RAISERROR (20036, 16, -1)
  5274.         return (1)
  5275.     END
  5276.     
  5277.         
  5278. DECLARE DC CURSOR LOCAL FAST_FORWARD for select DISTINCT name, category from master..sysdatabases 
  5279.     where (category & 4) = 4 or (category & 1 = 1)
  5280.     for read only
  5281.     open DC
  5282.     fetch DC into @publisher_db, @category
  5283.     WHILE (@@fetch_status <> -1)
  5284.     BEGIN
  5285.         if (@category & 4 = 4)
  5286.             begin
  5287.                 select @proc_name = @publisher_db + '.dbo.sp_MSdrop_expired_mergesubscription'
  5288.                 exec @retcode = @proc_name
  5289.                 if @retcode<>0 or @@ERROR<>0
  5290.                     goto DONE
  5291.             end
  5292.         if (@category & 1 = 1)
  5293.             begin
  5294.                 select @proc_name = @publisher_db + '.dbo.sp_MSdrop_expired_subscription'
  5295.                 exec @retcode = @proc_name
  5296.                 if @retcode<>0 or @@ERROR<>0
  5297.                     goto DONE
  5298.             end    
  5299.     fetch DC into @publisher_db, @category
  5300.     END
  5301.  
  5302.     /*
  5303.     ** sp_MScleanup_agent_entry in distribution database is called to periodically remove obselete
  5304.     ** entries in MSmerge_agents, which may be caused by the following reasons:
  5305.     **  1. publishing database is externally removed; therefore cleanup agent can not do its job
  5306.     **  2. Entries for anonymous merge subscriptions
  5307.     */
  5308.     SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '..sp_MScleanup_agent_entry'
  5309.     exec @retcode = @distproc 
  5310.     if @@ERROR<>0 or @retcode<>0
  5311.     BEGIN
  5312.         close DC
  5313.         deallocate DC
  5314.         return (1)
  5315.     END
  5316.  
  5317. DONE:
  5318.     close DC
  5319.     deallocate DC
  5320. GO
  5321.  
  5322. go
  5323. exec dbo.sp_MS_marksystemobject sp_expired_subscription_cleanup
  5324. go
  5325. grant execute on dbo.sp_expired_subscription_cleanup to public
  5326.  
  5327.  
  5328. raiserror('Creating procedure sp_addmergepullsubscription', 0,1)
  5329. GO
  5330.  
  5331. CREATE PROCEDURE sp_addmergepullsubscription (
  5332.     @publication             sysname,                      /* Publication name */
  5333.     @publisher                sysname = @@SERVERNAME,      /* Publisher server */
  5334.     @publisher_db            sysname = NULL,              /* Publication database */
  5335.     @subscriber_type         nvarchar(15) = 'local',            /* Subscriber type */ 
  5336.     @subscription_priority     real         = NULL,                /* Subscription priority */
  5337.     @sync_type                 nvarchar(15) = 'automatic', /* subscription sync type */
  5338.     @description nvarchar(255) = NULL              
  5339.      ) AS
  5340.  
  5341.     SET NOCOUNT ON
  5342.  
  5343.     /*
  5344.     ** Declarations.
  5345.     */
  5346.     declare @retcode                int
  5347.     declare    @subscriber_db            sysname
  5348.     declare @subnickname            int
  5349.     declare @subscriber_srvid        int 
  5350.     declare @publisher_srvid        int 
  5351.     declare @priority                 real
  5352.     declare @subid                     uniqueidentifier
  5353.     declare @subscriber_typeid         smallint
  5354.     declare @subscription_type         smallint
  5355.     declare @command                 nvarchar(255)
  5356.     declare @inactive                tinyint 
  5357.     declare @global                 tinyint        /* subscriber type is global */
  5358.     declare @push                     tinyint        /* subscription type is push */
  5359.      
  5360.     declare @sync_typeid             tinyint
  5361.     declare @nosync                 tinyint        
  5362.     declare @automatic                tinyint             
  5363.     declare @pubid                    uniqueidentifier             
  5364.     declare @partnerid                uniqueidentifier             
  5365.     declare @parentid               uniqueidentifier
  5366.  
  5367.     /*
  5368.     ** Initializations.
  5369.     */
  5370.  
  5371.     SET @nosync             = 2       /* Const: synchronization type 'nosync' */
  5372.     SET @automatic             = 1       /* Const: synchronization type 'automatic' */
  5373.     SET @inactive             = 0
  5374.     SET @global             = 1
  5375.     SET @push                 = 0   
  5376.  
  5377.  
  5378.     set @pubid                 = newid()
  5379.     set @partnerid            = @pubid
  5380.     
  5381.     set @parentid            = '00000000-0000-0000-0000-000000000000'
  5382.      
  5383.     /* 
  5384.     ** Check if replication components are installed on this server
  5385.     */
  5386.     exec @retcode = dbo.sp_MS_replication_installed
  5387.     if (@retcode <> 1)
  5388.     begin
  5389.         return (1)
  5390.     end
  5391.  
  5392.     /*
  5393.     ** Security Check.
  5394.     */
  5395.  
  5396.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  5397.     if @@ERROR <> 0 or @retcode <> 0
  5398.         return(1)
  5399.  
  5400.     /*
  5401.     **    Check to see if merge system tables exist. Create them unless they already
  5402.     **  exist.
  5403.     */
  5404.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  5405.         BEGIN
  5406.             execute @retcode = dbo.sp_MScreate_mergesystables
  5407.                 if @@ERROR <> 0 or @retcode <> 0
  5408.                     begin
  5409.                         return (1)
  5410.                     end
  5411.         END    
  5412.  
  5413.     if UPPER(@publisher) = UPPER(@@SERVERNAME) and @publisher_db = db_name()
  5414.         begin
  5415.             raiserror(21126, 16, -1)
  5416.             return (1)
  5417.         end
  5418.  
  5419.     if exists (select pubid from sysmergepublications where UPPER(publisher) = UPPER(@@SERVERNAME) and publisher_db=db_name()) and @subscriber_type in ('local', 'anonymous')
  5420.         begin
  5421.             declare @dbname sysname
  5422.             select @dbname = DB_NAME()
  5423.             raiserror(21127, 16, -1, @dbname)
  5424.             return (1)
  5425.         end
  5426.     /* 
  5427.     ** When adding a pull subscription, if a push subscription for that publication already exists, 
  5428.     ** we will cleanup all the traces of that subscription
  5429.     */
  5430.     IF EXISTS (select name from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db)
  5431.     BEGIN
  5432.         select @pubid=pubid from sysmergepublications 
  5433.             where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  5434.         IF EXISTS (select subid from sysmergesubscriptions where pubid=@pubid and subid<>@pubid and subscription_type=0)
  5435.             begin
  5436.                 exec @retcode = dbo.sp_MSpublicationcleanup @publisher=@publisher,
  5437.                                                         @publisher_db=@publisher_db,
  5438.                                                         @publication=@publication
  5439.                 IF @@ERROR <> 0 or @retcode <>0
  5440.                     BEGIN
  5441.                     RAISERROR (20025, 16, -1, @publication)
  5442.                     return (1)
  5443.                     END    
  5444.             end
  5445.         ELSE
  5446.             begin
  5447.                 IF EXISTS (select status from sysmergesubscriptions where pubid=@pubid and status =    2)
  5448.                     begin
  5449.                         select @subid = subid from sysmergesubscriptions where pubid=@pubid and subid<>pubid
  5450.                         delete sysmergesubscriptions where pubid=@pubid
  5451.                         delete MSmerge_replinfo where repid = @subid
  5452.                     end
  5453.                 ELSE 
  5454.                     begin
  5455.                         RAISERROR (14058, 16, -1)
  5456.                         return (1)
  5457.                     end
  5458.             end
  5459.     END
  5460.     
  5461.     set @partnerid = @pubid
  5462.      
  5463.       /*
  5464.     ** Assign parameter values appropriately for the local server database
  5465.     */
  5466.     set @subscriber_db = DB_NAME()
  5467.     select @subscriber_srvid = 0
  5468.  
  5469.     /*
  5470.     ** Parameter Check: @publisher
  5471.     ** Check to make sure that the publisher is defined
  5472.     */
  5473.     IF @publisher IS NULL
  5474.     BEGIN
  5475.         RAISERROR (14043, 16, -1, '@publisher')
  5476.         RETURN (1)
  5477.     END
  5478.  
  5479.     IF LOWER(@publisher) = 'all'
  5480.     BEGIN
  5481.         RAISERROR (14136, 16, -1)
  5482.         RETURN (1)
  5483.     END
  5484.  
  5485.     EXECUTE @retcode = dbo.sp_validname @publisher
  5486.     IF @@ERROR <> 0 OR @retcode <> 0
  5487.        RETURN (1)
  5488.     /*
  5489.     ** Validate that the publisher is a valid server
  5490.     */
  5491.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  5492.     IF @publisher_srvid IS NULL
  5493.         BEGIN
  5494.             EXECUTE @retcode = dbo.sp_addserver @publisher
  5495.             IF @@error <> 0 OR @retcode <> 0
  5496.                 BEGIN
  5497.                     RAISERROR (14010, 16, -1)
  5498.                        RETURN (1)
  5499.                 END
  5500.             ELSE
  5501.                 select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  5502.         END
  5503.  
  5504.  
  5505.     /*
  5506.     ** Parameter Check: @publisher_db
  5507.     */
  5508.     IF @publisher_db IS NULL
  5509.     BEGIN
  5510.         RAISERROR (14043, 16, -1, '@publisher_db')
  5511.         RETURN (1)
  5512.     END
  5513.  
  5514.     IF LOWER(@publisher_db) = 'all'
  5515.     BEGIN
  5516.         RAISERROR (14136, 16, -1)
  5517.         RETURN (1)
  5518.     END
  5519.     
  5520.     /*
  5521.     ** Check to see if the publication name is already used in the subscription 
  5522.     ** database - This is the case where we are resubscribing to the same publication.
  5523.     ** Execute dbo.sp_MSpublicationcleanup to cleanup all all the defunct rows
  5524.     
  5525.     ** if exists (select * from sysmergepublications where name = @publication)
  5526.     ** begin
  5527.     **    exec @retcode = dbo.sp_MSpublicationcleanup 
  5528.     **    IF @@ERROR <> 0 OR @retcode <> 0
  5529.     **        BEGIN
  5530.     **            RAISERROR (20025, 16, -1, @publication)
  5531.     **            RETURN (1)
  5532.     **        END                        
  5533.     ** end
  5534.     */
  5535.  
  5536.     /*
  5537.     ** Parameter Check: @subscriber_type.
  5538.     ** Set subscriber_typeid based on the @subscriber_type specified.
  5539.     **
  5540.     **   subscriber_type     subscriber_type
  5541.     **   =================    ===============
  5542.     **             1             global
  5543.     **             2             local
  5544.     **             3             anonymous
  5545.     **             NO support for republisher for B 3
  5546.     */
  5547.     if LOWER(@subscriber_type) NOT IN ('local', 'global', 'anonymous')
  5548.         BEGIN
  5549.               RAISERROR (20023, 16, -1)
  5550.             RETURN (1)
  5551.         END
  5552.  
  5553.     set @subscription_type = 1 /* pull by default */
  5554.     if LOWER(@subscriber_type) IN ('global')
  5555.         set @subscriber_typeid = 1
  5556.     else if LOWER(@subscriber_type) IN ('local')
  5557.         set @subscriber_typeid = 2
  5558.     else if LOWER(@subscriber_type) IN ('anonymous')       
  5559.         begin
  5560.             /* For anonymous subscribers set subscription type appropriately */
  5561.             set @subscriber_typeid = 3
  5562.             set @subscription_type = 2
  5563.         end            
  5564.  
  5565.     /* 
  5566.     ** Assign priority appropriately - choose 0.99 times the minimum priority
  5567.     ** of the global replicas.
  5568.     */
  5569.     if (@subscription_priority > 100.0 or @subscription_priority < 0.0)
  5570.         set @subscription_priority = NULL        
  5571.     if (@subscription_priority IS NULL)
  5572.         begin
  5573.             select @priority = 0.99 * min(priority) from sysmergesubscriptions where subscriber_type  = 1 /* global/loopback */
  5574.             if (@priority IS NOT NULL)
  5575.                 select @subscription_priority = @priority
  5576.             if (@subscription_priority IS NULL) 
  5577.                 select @subscription_priority = 0.0
  5578.         end
  5579.     /*
  5580.     ** For local and anonymous subscriptions the priority is 0.0
  5581.     */
  5582.     if LOWER(@subscriber_type) IN ('local', 'anonymous')
  5583.         select @subscription_priority = 0.0
  5584.  
  5585.     /*
  5586.      ** If the subscription already exists, don't add it.
  5587.     
  5588.      ** if EXISTS (select db_name, srvid
  5589.      **        FROM sysmergesubscriptions
  5590.     **         WHERE db_name = @subscriber_db
  5591.     **         AND srvid = @subscriber_srvid                           
  5592.     **        AND pubid = @pubid)
  5593.     **    BEGIN
  5594.     **        RAISERROR (14058, 16, -1)
  5595.     **        RETURN (1)
  5596.      **    END
  5597.     */
  5598.  
  5599.    /*
  5600.    ** Parameter Check: @sync_type.
  5601.    ** Set sync_typeid based on the @sync_type specified.
  5602.    **
  5603.    **   sync_typeid     sync_type
  5604.    **   ===========     =========
  5605.    **             1     automatic
  5606.    **             2     nosync
  5607.    */
  5608.  
  5609.  
  5610.    IF LOWER(@sync_type) NOT IN ('automatic', 'none')
  5611.        BEGIN
  5612.            RAISERROR (14052, 16, -1)
  5613.            RETURN (1)
  5614.        END
  5615.  
  5616.  
  5617.    IF LOWER(@sync_type) = 'automatic'
  5618.    BEGIN
  5619.         SET @sync_typeid = @automatic
  5620.    END
  5621.    ELSE
  5622.    BEGIN
  5623.         SET @sync_typeid = @nosync
  5624.    END
  5625.  
  5626.  
  5627.     /*
  5628.     ** UNDONE: Validate that the publisher is of type 'republisher'
  5629.     */
  5630.  
  5631.     begin tran
  5632.     save TRAN addmergepullsubscription
  5633.         
  5634.         /* Generate a guid for the Subscriber ID */
  5635.         set @subid = newid()
  5636.  
  5637.         /* Look for existing nickname from any other subscription */
  5638.         exec dbo.sp_MSgetreplnick NULL, NULL , NULL,  @subnickname out
  5639.         if (@@error <> 0) 
  5640.             begin
  5641.             goto FAILURE
  5642.             end                 
  5643.  
  5644.  
  5645.         /* Generate a new replica nickname from the @subid */
  5646.         if (@subnickname is null)
  5647.             EXECUTE dbo.sp_MSgenreplnickname @subid, @subnickname output
  5648.  
  5649.     
  5650.         /* 
  5651.         ** Check to see if MSsubscription_properties table exists.
  5652.         ** If not, create it.
  5653.         */
  5654.         exec @retcode = dbo.sp_MScreate_sub_tables
  5655.         IF @@ERROR <> 0 or @retcode <> 0
  5656.             goto FAILURE
  5657.  
  5658.         /*
  5659.         ** The subscription doesn't exist, so let's add it to sysmergesubscriptions 
  5660.         */
  5661.         INSERT sysmergesubscriptions (subid, partnerid, datasource_type, srvid, db_name, 
  5662.                 pubid, status, subscriber_type, subscription_type, priority, sync_type, description, login_name)
  5663.                     VALUES (@subid,
  5664.                             @partnerid,
  5665.                             0,
  5666.                             @subscriber_srvid,
  5667.                             @subscriber_db,
  5668.                             @pubid,
  5669.                             @inactive,
  5670.                             @subscriber_typeid,
  5671.                             @subscription_type,     /* for a pull/anon subscription */
  5672.                             @subscription_priority,
  5673.                             @sync_typeid,
  5674.                             @description,
  5675.                             suser_sname(suser_sid()))            
  5676.         if @@ERROR <> 0
  5677.             BEGIN
  5678.                 GOTO FAILURE
  5679.             END
  5680.  
  5681.         /* Add a self-subscribed subscription to represent the publication */
  5682.             
  5683.         insert sysmergepublications(publisher, publisher_db, pubid, name, parentid) 
  5684.             values(@publisher, @publisher_db, @pubid, @publication, @parentid)
  5685.         if @@ERROR <> 0
  5686.             begin
  5687.                 goto FAILURE
  5688.             end
  5689.         insert sysmergesubscriptions(subid, partnerid, datasource_type, srvid, db_name, 
  5690.                 pubid, subscriber_type, subscription_type, status, priority, sync_type, description, login_name)
  5691.             values (@pubid, @pubid, 0, @publisher_srvid, @publisher_db, 
  5692.                 @pubid, @global, @push, @inactive, 100.0, @sync_typeid, @description, suser_sname(suser_sid()))  
  5693.                         
  5694.         if @@ERROR <> 0
  5695.             begin
  5696.                 goto FAILURE
  5697.             end
  5698.                     
  5699.         /*
  5700.         **  Add row for subscription in MSmerge_replinfo.
  5701.         */
  5702.         insert MSmerge_replinfo(repid, replnickname)
  5703.                 values (@subid, @subnickname)
  5704.         if @@ERROR <> 0
  5705.             BEGIN
  5706.                 GOTO FAILURE
  5707.             END
  5708.  
  5709.     COMMIT TRAN
  5710.     return (0)
  5711.  
  5712. FAILURE:
  5713.     RAISERROR (14057, 16, -1)
  5714.     if @@trancount > 0
  5715.     begin
  5716.         ROLLBACK TRANSACTION addmergepullsubscription
  5717.         COMMIT TRANSACTION
  5718.     end
  5719.     RETURN (1)
  5720.  
  5721. go
  5722. exec dbo.sp_MS_marksystemobject sp_addmergepullsubscription 
  5723. go
  5724.  
  5725. grant execute on dbo.sp_addmergepullsubscription to public
  5726. go
  5727.  
  5728. raiserror('Creating procedure sp_changemergepullsubscription', 0,1)
  5729. GO
  5730.  
  5731. CREATE PROCEDURE sp_changemergepullsubscription (
  5732.     @publication         sysname = '%',    /* Publication name */
  5733.     @publisher            sysname = '%',  /* Publisher server */
  5734.     @publisher_db        sysname = '%',     /* Publication database */
  5735.     @property             sysname = NULL, /* The property to change */
  5736.     @value                 nvarchar(255) = NULL    /* The new property value */
  5737.     ) AS
  5738.  
  5739.     SET NOCOUNT ON
  5740.  
  5741.     /*
  5742.     ** Declarations.
  5743.     */
  5744.     declare @subscriber_srvid         int
  5745.     declare @publisher_srvid         int
  5746.     declare @retcode                 int
  5747.     declare    @pubid                     uniqueidentifier
  5748.     declare    @subid                     uniqueidentifier
  5749.     declare    @partnerid                 uniqueidentifier
  5750.     declare @sync_typeid             tinyint
  5751.     declare @nosync                 tinyint
  5752.     declare @automatic                 tinyint
  5753.      
  5754.     declare @artid                    uniqueidentifier
  5755.     declare @subscriber                sysname
  5756.     declare @subscriber_db            sysname
  5757.     declare @schematype                int
  5758.     declare @schemaversion            int
  5759.     declare @schemaguid                uniqueidentifier
  5760.     declare @db_name                sysname
  5761.     declare @subscriber_type        int
  5762.     declare @schematext                nvarchar(2000)
  5763.      
  5764.  
  5765.     /*
  5766.     ** Initializations.
  5767.     */
  5768.     SET @subscriber     = @@SERVERNAME
  5769.     SET @subscriber_db    = DB_NAME()
  5770.     SET @nosync         = 2     /* Const: synchronization type 'none' */
  5771.     SET @automatic         = 1     /* Const: synchronization type 'automatic' */
  5772.  
  5773.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  5774.     IF @subscriber_srvid IS NULL
  5775.         BEGIN
  5776.            RAISERROR (14010, 16, -1)
  5777.            RETURN (1)     
  5778.         END
  5779.  
  5780.     /*
  5781.     ** Security Check.
  5782.     */
  5783.     BEGIN
  5784.         exec @retcode = dbo.sp_MSreplcheck_subscribe
  5785.         if @@ERROR <> 0 or @retcode <> 0
  5786.             return(1)
  5787.     END
  5788.  
  5789.  
  5790.     /*
  5791.     **    Check to see if current database is enabled for subscribing
  5792.     */
  5793.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  5794.         BEGIN
  5795.             RAISERROR (14055, 16, -1)
  5796.             RETURN (1)
  5797.         END
  5798.  
  5799.     
  5800.     /*
  5801.     ** Parameter Check:  @property.
  5802.     ** If the @property parameter is NULL, print the options.
  5803.     */
  5804.  
  5805.     IF @property IS NULL
  5806.         BEGIN
  5807.             CREATE TABLE #tab1 (properties sysname NOT NULL)
  5808.             INSERT INTO #tab1 VALUES ('sync_type')
  5809.             INSERT INTO #tab1 VALUES ('priority')
  5810.             INSERT INTO #tab1 VALUES ('description') 
  5811.             select * FROM #tab1
  5812.             RETURN (0)
  5813.         END
  5814.  
  5815.     /*
  5816.     ** Parameter Check:  @publisher.
  5817.     ** Check to make sure we have a valid publisher.
  5818.     ** Should make sure that @publisher is non-null before using it to check whether @publication is valid
  5819.     */
  5820.     IF @publisher IS NULL
  5821.         BEGIN
  5822.             RAISERROR (14043, 16, -1, '@publisher')
  5823.             RETURN (1)
  5824.         END
  5825.  
  5826.     /*
  5827.     ** Parameter Check:  @publication.
  5828.     ** Make sure that the publication exists.
  5829.     */
  5830.  
  5831.     IF @publication IS NULL
  5832.         BEGIN
  5833.             RAISERROR (14043, 16, -1, '@publication')
  5834.             RETURN (1)
  5835.         END
  5836.  
  5837.     select @pubid = pubid FROM sysmergepublications WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  5838.     IF @pubid IS NULL
  5839.         BEGIN
  5840.             RAISERROR (20026, 11, -1, @publication)
  5841.             RETURN (1)
  5842.         END
  5843.  
  5844.     /*
  5845.     ** Validate that the publisher is a valid server
  5846.     */
  5847.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  5848.     IF @publisher_srvid IS NULL
  5849.         BEGIN
  5850.             RAISERROR (14010, 16, -1)
  5851.                RETURN (1)
  5852.         END
  5853.  
  5854.     /*
  5855.     ** Check to see if you have a local / global subscription on this publication
  5856.     */
  5857.     set @subid = NULL
  5858.     select @subid = subs1.subid, 
  5859.     @pubid = pubs.pubid, /* identified from publication name */
  5860.     @subscriber_type=subs1.subscriber_type,
  5861.         @partnerid = subs2.subid from
  5862.         sysmergesubscriptions     subs1,
  5863.           sysmergesubscriptions     subs2,
  5864.         sysmergepublications     pubs
  5865.         where subs1.srvid = @subscriber_srvid
  5866.             and subs1.db_name = @subscriber_db
  5867.             and subs2.srvid = @publisher_srvid
  5868.             and subs2.db_name = @publisher_db
  5869.             and subs1.pubid = subs2.subid
  5870.             and subs2.pubid = pubs.pubid
  5871.             and pubs.name = @publication
  5872.             and UPPER(pubs.publisher)=UPPER(@publisher)
  5873.             and pubs.publisher_db = @publisher_db
  5874.  
  5875.     if @subid IS NULL 
  5876.          begin
  5877.             RAISERROR (14050, 11, -1)
  5878.             RETURN(1)
  5879.         end                 
  5880.  
  5881.     /*
  5882.     ** Parameter Check:  @property.
  5883.     ** Check to make sure that @property is a valid property in
  5884.     ** sysarticles.
  5885.     */
  5886.  
  5887.     
  5888.     IF LOWER(@property) NOT IN ('sync_type', 'priority', 'description')
  5889.         BEGIN
  5890.             RAISERROR (14051, 16, -1)
  5891.             RETURN (1)
  5892.         END
  5893.  
  5894.     /*
  5895.     ** Change the property.
  5896.     */
  5897.     IF LOWER(@property) = 'sync_type'
  5898.         BEGIN
  5899.  
  5900.             /*
  5901.             ** Check to make sure that we have a valid sync_type.
  5902.             */
  5903.  
  5904.             IF LOWER(@value) NOT IN ('automatic', 'none')
  5905.                 BEGIN
  5906.                     RAISERROR (14052, 16, -1)
  5907.                     RETURN (1)
  5908.                 END
  5909.  
  5910.             /*
  5911.             ** Determine the integer value for the sync_type.
  5912.             */
  5913.  
  5914.             IF LOWER(@value) = 'automatic'
  5915.                 SET @sync_typeid = @automatic
  5916.             ELSE
  5917.                 SET @sync_typeid = @nosync
  5918.  
  5919.             /*
  5920.             ** Update the subscription with the new sync_type.
  5921.             */
  5922.  
  5923.             UPDATE sysmergesubscriptions
  5924.                    SET sync_type = @sync_typeid
  5925.                  WHERE subid = @subid
  5926.             IF @@ERROR <> 0
  5927.                 BEGIN
  5928.                     RAISERROR (14053, 16, -1)
  5929.                     RETURN (1)
  5930.                 END
  5931.  
  5932.         END
  5933.         
  5934.     IF LOWER(@property) = 'description'
  5935.         BEGIN
  5936.         UPDATE sysmergesubscriptions
  5937.                    SET description = @value
  5938.                  WHERE subid = @subid
  5939.             IF @@ERROR <> 0
  5940.                 BEGIN
  5941.                     RAISERROR (14053, 16, -1) 
  5942.               
  5943.                     RETURN (1)
  5944.                 END
  5945.  
  5946.         END
  5947.         
  5948.      
  5949.     IF LOWER(@property) = 'priority'
  5950.     BEGIN
  5951.  
  5952.     select @db_name = db_name from sysmergesubscriptions
  5953.         where (pubid=@pubid) and (subid=@pubid)
  5954.         IF @db_name <> db_name()
  5955.         BEGIN
  5956.             RAISERROR (20047, 16, -1)
  5957.             RETURN (1)
  5958.         END
  5959.  
  5960.     /* Only the original publisher can change priority of a global subscriptions */
  5961.  
  5962.         IF @subscriber_type<>1  
  5963.         BEGIN
  5964.             RAISERROR (20044, 16, -1)  /* Local subscriber does not have priority*/
  5965.             RETURN (1)
  5966.         END
  5967.         
  5968.          select @schemaversion = schemaversion from sysmergeschemachange
  5969.         if (@schemaversion is NULL)
  5970.         set @schemaversion = 1
  5971.         else
  5972.             select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange
  5973.             
  5974.          
  5975.         set @schemaguid = newid()
  5976.         set @artid = newid()
  5977.         set @schematype = 8 /* change priority */
  5978.         select @schematext = 'exec dbo.sp_MSchange_priority '+ '''' + convert(nchar(36),@subid) + '''' + ',' + '''' + @value + '''' 
  5979.          
  5980.     BEGIN TRANSACTION
  5981.         exec dbo.sp_MSchange_priority @subid,  @value
  5982.          exec dbo.sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
  5983.     COMMIT TRANSACTION
  5984.     
  5985.     END
  5986.     
  5987.     /*
  5988.     ** Return succeed.
  5989.     */
  5990.  
  5991.     RAISERROR (14054, 10, -1)
  5992.     RETURN (0)
  5993. go
  5994.  
  5995. exec dbo.sp_MS_marksystemobject sp_changemergepullsubscription 
  5996. go
  5997.  
  5998. grant execute on dbo.sp_changemergepullsubscription to public
  5999. go
  6000.  
  6001.  
  6002. raiserror('Creating procedure sp_helpmergepullsubscription', 0,1)
  6003. GO
  6004.  
  6005. CREATE PROCEDURE sp_helpmergepullsubscription(
  6006.     @publication         sysname = '%',        /* Publication name */
  6007.     @publisher            sysname = '%',      /* Publisher server */
  6008.     @publisher_db        sysname = '%',      /* Publication database */
  6009.     @subscription_type    nvarchar(10) = 'pull'    /* Show only pull subscriptions */
  6010.     )AS
  6011.     
  6012.     SET NOCOUNT ON
  6013.  
  6014.     /*
  6015.     ** Declarations.
  6016.     */
  6017.  
  6018.     declare @retcode             int
  6019.     declare @srvid                 int
  6020.     declare    @pubid                 uniqueidentifier
  6021.     declare    @subid                 uniqueidentifier
  6022.     declare    @partnerid             uniqueidentifier
  6023.     declare @cursor_open        int
  6024.     declare @subscriber            sysname
  6025.     declare @subscriber_db        sysname
  6026.     declare @subscription_set     nvarchar(10)
  6027.     declare @publisher_local    sysname
  6028.     declare @publisher_db_local    sysname
  6029.     declare @publication_local    sysname
  6030.     declare @subscription_name     nvarchar(1000)
  6031.     declare @regkey                nvarchar(1000)
  6032.     declare @time                smalldatetime
  6033.     declare @syncmgr_keyexist                int
  6034.     declare @helpsubscriptioncursor_open    int
  6035.     
  6036.  
  6037.     /*
  6038.     ** Initializations.
  6039.     */
  6040.     set @cursor_open             = 0                    
  6041.  
  6042.     select @publisher_db = RTRIM(@publisher_db)
  6043.     select @publication = RTRIM(@publication)
  6044.     
  6045.     /*
  6046.     **    Calling sp_help* is all right whether current database is enabled for pub/sub or not
  6047.     */
  6048.  
  6049.     IF not exists (select * from sysobjects where name='sysmergesubscriptions')
  6050.         RETURN (0)
  6051.  
  6052.     /* Security check */
  6053.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  6054.     if @@ERROR <> 0 or @retcode <> 0
  6055.         return(1)
  6056.  
  6057.     set @subscriber = @@SERVERNAME     
  6058.     set @subscriber_db = DB_NAME()
  6059.  
  6060.     /*
  6061.     ** Parameter Check: @publisher
  6062.     ** Check to make sure that the publisher is defined
  6063.     */
  6064.     IF @publisher <> '%' AND @publisher IS NOT NULL
  6065.     BEGIN
  6066.         EXECUTE @retcode = dbo.sp_validname @publisher
  6067.  
  6068.         IF @@ERROR <> 0 OR @retcode <> 0
  6069.                RETURN (1)
  6070.     END
  6071.  
  6072.     /*
  6073.     ** Parameter Check:  @publication.
  6074.     ** If the publication name is specified, check to make sure that it
  6075.     ** conforms to the rules for identifiers and that the publication
  6076.     ** actually exists.  Disallow NULL.
  6077.     */
  6078.     if @publication IS NULL
  6079.         BEGIN
  6080.             RAISERROR (14043, 16, -1, '@publication')
  6081.             RETURN (1)
  6082.         END
  6083.  
  6084.     /*
  6085.     ** Parameter Check: @subscription_type.
  6086.     ** Set subscription_typeid based on the @subscription_type specified.
  6087.     **
  6088.     **   subscription_type    subscription_type
  6089.     **   =================    ===============
  6090.     **             0             push
  6091.     **             1             pull
  6092.     **              0,1            both
  6093.     */
  6094.     if LOWER(@subscription_type) NOT IN ('push', 'pull', 'both')
  6095.         BEGIN
  6096.               RAISERROR (14128, 16, -1)
  6097.             RETURN (1)
  6098.         END
  6099.     IF LOWER(@subscription_type) = 'both'
  6100.         set @subscription_set = '(0, 1)'
  6101.     else IF LOWER(@subscription_type) = 'push'
  6102.         set @subscription_set = '(0)'
  6103.     else 
  6104.         set @subscription_set = '(1,2)'   -- including pull subscription and pull/anonymous subscription
  6105.  
  6106.     /*
  6107.     ** Get subscriptions
  6108.     */
  6109.     
  6110.     create table #helpmergepullsubscription
  6111.                 (
  6112.                     publication                sysname        NOT NULL,
  6113.                     publisher                sysname        NOT NULL,
  6114.                     publisher_db            sysname        NOT NULL,
  6115.                     subscriber                sysname        NOT NULL,
  6116.                     subscriber_db             sysname        NOT NULL,
  6117.                     status                    int         NOT NULL,
  6118.                     subscriber_type         int            NOT NULL,
  6119.                     subscription_type         int            NOT NULL,
  6120.                     priority                float(8)    NOT NULL,
  6121.                     sync_type                tinyint        NOT NULL,
  6122.                     description                nvarchar(255) NULL,
  6123.                     merge_jobid                binary(16)    NULL,
  6124.                     enabled_for_syncmgr        int            NULL,
  6125.                     last_updated            nvarchar(40) NULL
  6126.                 )
  6127.  
  6128.     IF @publisher IS NULL and @publisher_db IS NULL
  6129.         BEGIN
  6130.             select @subid = subid from sysmergesubscriptions where subid = partnerid
  6131.             set @partnerid = @subid
  6132.             -- show the loopback subscription
  6133.             insert into #helpmergepullsubscription 
  6134.                 select pubs.name, servers2.srvname, subs2.db_name, servers1.srvname, subs1.db_name, 
  6135.                     subs1.status, subs1.subscriber_type, subs1.subscription_type, subs1.priority, 
  6136.                     subs1.sync_type, subs1.description, replinfo.merge_jobid, 0, NULL
  6137.                 FROM      sysmergesubscriptions     subs1,
  6138.                           sysmergesubscriptions     subs2,
  6139.                           MSmerge_replinfo         replinfo,
  6140.                         master..sysservers         servers1,
  6141.                         master..sysservers         servers2,
  6142.                         sysmergepublications     pubs
  6143.                 where subs1.subid = @subid
  6144.                     and subs2.subid = @partnerid
  6145.                     and pubs.pubid = subs1.pubid
  6146.                     and servers1.srvid = subs1.srvid
  6147.                     and servers2.srvid = subs2.srvid
  6148.                     and subs1.subid = subs1.partnerid 
  6149.                     and replinfo.repid = subs1.subid 
  6150.             
  6151.         END
  6152.     else
  6153.         begin
  6154.             declare #cursor cursor local FAST_FORWARD FOR select DISTINCT sub.subid, sub.partnerid 
  6155.                 FROM sysmergesubscriptions     sub,
  6156.                 sysmergesubscriptions         sub1, 
  6157.                 master..sysservers             ss,  
  6158.                 master..sysservers             ss1, 
  6159.                 sysmergepublications         pub 
  6160.                  WHERE ((@subscriber = N'%') OR (UPPER(ss.srvname) = UPPER(@subscriber))) 
  6161.                     AND ((@publisher = N'%') OR (UPPER(ss1.srvname) = UPPER(@publisher))) 
  6162.                     AND sub1.srvid = ss1.srvid 
  6163.                        AND sub.srvid = ss.srvid  
  6164.                        AND pub.name LIKE  @publication  
  6165.                        AND sub.pubid = pub.pubid 
  6166.                        AND sub.db_name LIKE  @subscriber_db 
  6167.                        AND sub1.db_name LIKE @publisher_db 
  6168.                     AND sub1.pubid = pub.pubid 
  6169.                     AND (sub.subscription_type=1 or sub.subscription_type=2) 
  6170.                 FOR READ ONLY
  6171.  
  6172.             open #cursor
  6173.             select @cursor_open = 1                    
  6174.             fetch next from #cursor into @subid, @partnerid
  6175.             while (@@fetch_status <> -1)
  6176.                 begin
  6177.                     insert into #helpmergepullsubscription 
  6178.                         select pubs.name, servers2.srvname, subs2.db_name, servers1.srvname, subs1.db_name, 
  6179.                             subs1.status, subs1.subscriber_type, subs1.subscription_type, subs1.priority, 
  6180.                             subs1.sync_type, subs1.description, replinfo.merge_jobid, 0, NULL
  6181.                         FROM      sysmergesubscriptions     subs1,
  6182.                                   sysmergesubscriptions     subs2,
  6183.                                   MSmerge_replinfo         replinfo,
  6184.                                 master..sysservers         servers1,
  6185.                                 master..sysservers         servers2,
  6186.                                 sysmergepublications     pubs
  6187.                         where subs1.subid = @subid
  6188.                             and subs2.subid = @partnerid
  6189.                             and pubs.pubid = subs1.pubid
  6190.                             and servers1.srvid = subs1.srvid
  6191.                             and servers2.srvid = subs2.srvid
  6192.                             and @subid <> @partnerid -- do not show the loopback subscription
  6193.                             and replinfo.repid = subs1.subid 
  6194.         
  6195.                     if @@ERROR <> 0
  6196.                         begin
  6197.                             set @retcode = 1
  6198.                             goto DONE
  6199.                         end                    
  6200.                 fetch next from #cursor into @subid, @partnerid
  6201.             end
  6202.         end
  6203.  
  6204.     declare #helpsubscriptioncursor CURSOR LOCAL FAST_FORWARD FOR 
  6205.         select DISTINCT publisher, publisher_db, publication
  6206.            FROM #helpmergepullsubscription
  6207.             FOR READ ONLY
  6208.     create table #syncmgr_keyexist (syncmgr_keyexist int)
  6209.     open #helpsubscriptioncursor
  6210.     select @helpsubscriptioncursor_open = 1                    
  6211.     fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local
  6212.     while (@@fetch_status <> -1)
  6213.         begin
  6214.             set @subscription_name = @publisher_local + ':' + @publisher_db_local + ':' + @publication_local + ':' + @subscriber + ':' + @subscriber_db
  6215.             /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  6216.             set @subscription_name = REPLACE(@subscription_name,'\','/')
  6217.             set @regkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\' + @subscription_name
  6218.             insert into #syncmgr_keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @regkey
  6219.             select @syncmgr_keyexist = syncmgr_keyexist from #syncmgr_keyexist
  6220.             update #helpmergepullsubscription set enabled_for_syncmgr = @syncmgr_keyexist 
  6221.                 where UPPER(publisher) = UPPER(@publisher_local)
  6222.                     and publisher_db = @publisher_db_local
  6223.                     and publication = @publication_local
  6224.             select @pubid = pubid from sysmergepublications where name=@publication_local
  6225.                                                             and UPPER(publisher) = UPPER(@publisher_local)
  6226.                                                             and publisher_db = @publisher_db_local
  6227.             select @time=max(coldate) from MSmerge_genhistory 
  6228.                 where art_nick in (select nickname from sysmergearticles where pubid=@pubid)
  6229.             update #helpmergepullsubscription set last_updated = convert(nvarchar(12), @time, 112) + substring(convert(nvarchar(24), @time, 121), 11,13) 
  6230.                 where UPPER(publisher) = UPPER(@publisher_local)
  6231.                     and publisher_db = @publisher_db_local
  6232.                     and publication = @publication_local 
  6233.             fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local
  6234.         end
  6235.  
  6236.     select 'subscription_name'= publisher + ':' + publisher_db + ':' + publication, *
  6237.                 from #helpmergepullsubscription 
  6238.             order by publisher, publisher_db, publication, subscriber, subscriber_db
  6239.          
  6240.     select @retcode = 0
  6241. DONE:
  6242.     if (@cursor_open = 1)
  6243.         begin
  6244.             close #cursor
  6245.             deallocate #cursor
  6246.         end            
  6247.     drop table #helpmergepullsubscription
  6248.  
  6249.     if (@helpsubscriptioncursor_open = 1)
  6250.         begin
  6251.             close #helpsubscriptioncursor
  6252.             deallocate #helpsubscriptioncursor
  6253.         end            
  6254.     drop table #syncmgr_keyexist    
  6255.     return @retcode    
  6256. go
  6257. exec dbo.sp_MS_marksystemobject sp_helpmergepullsubscription
  6258. go
  6259.  
  6260. grant execute on dbo.sp_helpmergepullsubscription to public
  6261. go
  6262.  
  6263. raiserror('Creating procedure sp_addmergepullsubscription_agent', 0,1)
  6264. GO
  6265. CREATE PROCEDURE sp_addmergepullsubscription_agent (
  6266.     @name                            sysname = NULL,
  6267.     @publisher                        sysname,                          /* Publisher server */
  6268.     @publisher_db                    sysname,                          /* Publisher database */
  6269.     @publication                     sysname,                          /* Publication name */
  6270.     @publisher_security_mode        int = 1,
  6271.     @publisher_login                sysname = NULL,
  6272.     @publisher_password                sysname = NULL,
  6273.     @publisher_encrypted_password    bit = 0,
  6274.     @subscriber                        sysname = NULL,
  6275.     @subscriber_db                    sysname = NULL,
  6276.     @subscriber_security_mode        int = NULL,                        /* 0 standard; 1 integrated */
  6277.     @subscriber_login                sysname = NULL,
  6278.     @subscriber_password            sysname = NULL,
  6279.     @distributor                    sysname = @@SERVERNAME,
  6280.     @distributor_security_mode        int = 1,                        /* 0 standard; 1 integrated */
  6281.     @distributor_login                sysname = NULL,
  6282.     @distributor_password            sysname = NULL,
  6283.     @encrypted_password                bit = 0,            /* distributor password encrypted or not */
  6284.     @frequency_type                  int = NULL,
  6285.     @frequency_interval             int = NULL,                
  6286.     @frequency_relative_interval     int = NULL, 
  6287.     @frequency_recurrence_factor     int = NULL, 
  6288.     @frequency_subday                 int = NULL,
  6289.     @frequency_subday_interval         int = NULL,       
  6290.     @active_start_time_of_day         int = NULL, 
  6291.     @active_end_time_of_day         int = NULL,         
  6292.     @active_start_date                 int = NULL, 
  6293.     @active_end_date                 int = NULL,
  6294.     @optional_command_line             nvarchar(255) = '',            /* Optional command line arguments */
  6295.     @merge_jobid                    binary(16) = NULL OUTPUT,
  6296.     @enabled_for_syncmgr nvarchar(5) = 'false', /* Enabled for SYNCMGR: true or false */
  6297.     @ftp_address sysname = NULL,
  6298.     @ftp_port int = NULL,
  6299.     @ftp_login sysname = NULL,
  6300.     @ftp_password sysname = NULL
  6301.     ) AS
  6302.  
  6303.     SET NOCOUNT ON
  6304.  
  6305.     /*
  6306.     ** Declarations.
  6307.     */
  6308.     declare @command                 nvarchar(4000)
  6309.     declare @retcode                 int
  6310.     declare @database                sysname
  6311.     declare @repid                    uniqueidentifier
  6312.     declare @pubid                    uniqueidentifier
  6313.     declare @subscriber_srvid        int 
  6314.     declare @publisher_srvid        int 
  6315.     declare @name_id                nvarchar(50)
  6316.     declare @subscriber_typeid        int
  6317.     declare @subscription_type_id    int
  6318.     declare @category_name            sysname
  6319.     declare @platform_nt            binary
  6320.     DECLARE @subscriber_enc_password sysname
  6321.  
  6322.     select @platform_nt = 0x1
  6323.  
  6324.     -- Set null @optional_command_line to empty string to avoid string concat problem
  6325.     if @optional_command_line is null
  6326.         set @optional_command_line = ''
  6327.  
  6328.     IF @distributor_password = N''
  6329.         select @distributor_password = NULL
  6330.  
  6331.     IF @publisher_password = N''
  6332.         select @publisher_password = NULL
  6333.  
  6334.     IF @ftp_password = N''
  6335.         select @ftp_password = NULL
  6336.  
  6337.     /*
  6338.     ** Parameter Check: @subscriber and @subscriber_db
  6339.     */
  6340.  
  6341.     if @subscriber IS NULL or rtrim(@subscriber) = ''
  6342.         SELECT @subscriber = @@SERVERNAME
  6343.  
  6344.     if @subscriber_db IS NULL or rtrim(@subscriber_db) = ''
  6345.         SELECT @subscriber_db = DB_NAME()
  6346.     
  6347.     EXECUTE @retcode = dbo.sp_validname @subscriber
  6348.     IF @@ERROR <> 0 OR @retcode <> 0
  6349.        RETURN (1)
  6350.     
  6351.     EXECUTE @retcode = dbo.sp_validname @subscriber_db
  6352.     IF @@ERROR <> 0 OR @retcode <> 0
  6353.        RETURN (1)
  6354.  
  6355.     -- Parameter check: @subscriber_security_mode    
  6356.     if @subscriber_security_mode is null
  6357.     begin
  6358.         if ( platform() & @platform_nt ) = @platform_nt
  6359.             select @subscriber_security_mode = 1
  6360.         else
  6361.             select @subscriber_security_mode = 0
  6362.     end    
  6363.  
  6364.     if ( ( platform() & @platform_nt ) <> @platform_nt and @subscriber_security_mode = 1)
  6365.     begin
  6366.         RAISERROR(21038, 16, -1)
  6367.         RETURN (1)
  6368.     end
  6369.  
  6370.     select @subscription_type_id = 1 /* pull agent only */
  6371.     /*
  6372.     ** Set Default schedule values if NULL is specified
  6373.     ** The default are not implemented during parmeter defintion because this procedure
  6374.     ** is can be called from sp_addmergesubscription.
  6375.     */
  6376.     if @frequency_type is NULL
  6377.         set @frequency_type = 4        /* Daily */
  6378.     if @frequency_interval is NULL
  6379.         set @frequency_interval = 1
  6380.     if @frequency_relative_interval is NULL
  6381.         set @frequency_relative_interval = 1
  6382.     if @frequency_recurrence_factor is NULL
  6383.         set @frequency_recurrence_factor = 0
  6384.     if @frequency_subday is NULL
  6385.         set @frequency_subday = 8    /* Hour */
  6386.     if @frequency_subday_interval is NULL
  6387.         set @frequency_subday_interval = 1
  6388.     if @active_start_time_of_day is NULL
  6389.         set @active_start_time_of_day = 0
  6390.     if @active_end_time_of_day is NULL
  6391.         set @active_end_time_of_day = 235959
  6392.     if @active_start_date is NULL
  6393.         set @active_start_date = 0
  6394.     if @active_end_date is NULL
  6395.         set @active_end_date = 99991231
  6396.  
  6397.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@@SERVERNAME)
  6398.     IF @subscriber_srvid IS NULL
  6399.         BEGIN
  6400.            RAISERROR (14010, 16, -1)
  6401.            RETURN (1)     
  6402.         END
  6403.             
  6404.     select @pubid = pubid from sysmergepublications where name = @publication
  6405.         IF @pubid is NULL
  6406.             begin
  6407.                 RAISERROR (14027, 16, -1, @publication)
  6408.                 RETURN (1)
  6409.             end
  6410.             
  6411.     select @repid = subid, @subscriber_typeid = subscriber_type from sysmergesubscriptions
  6412.             where srvid = @subscriber_srvid and pubid<>subid and pubid = @pubid
  6413.  
  6414.     if @subscriber_typeid = 3 set @subscription_type_id = 2 /* This corresponds to anonymous subscription */
  6415.  
  6416.     if (@subscription_type_id <> 0)
  6417.     begin
  6418.         if (@subscriber_security_mode = 0) and (@subscriber_login IS NULL or rtrim(@subscriber_login) = '')
  6419.         begin
  6420.             raiserror(3217, 16, -1, '@subscriber_login')
  6421.             return (1)
  6422.         end
  6423.     end
  6424.  
  6425.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  6426.     begin
  6427.         raiserror(14027, 16, -1, 'The subscription properties table ''MSsubscription_properties''')
  6428.         return (1)
  6429.     end
  6430.     
  6431.     /*
  6432.     ** Construct unique task name if @name = NULL
  6433.     */
  6434.     IF @name IS NULL
  6435.         begin
  6436.              SELECT @name = CONVERT(nvarchar(23),@publisher ) + '-' + CONVERT(nvarchar(23),@publisher_db) + '-' + 
  6437.                         CONVERT(nvarchar(23),@publication) + '-' + CONVERT(nvarchar(23),@subscriber) + '-' +
  6438.                         CONVERT(nvarchar(23), @subscriber_db) + '- 0'
  6439.         end
  6440.     else
  6441.     begin
  6442.         /*
  6443.         ** validate name
  6444.         */
  6445.         exec @retcode = dbo.sp_MSreplcheck_name @name
  6446.         if @@ERROR <> 0 or @retcode <> 0
  6447.             return(1)
  6448.  
  6449.     end
  6450.     /* Construct task command */
  6451.     select @command = '-Publisher ' + @publisher + ' -PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  6452.     select @command = @command + '-Publication ' + QUOTENAME(@publication) + ' '
  6453.     select @command = @command + '-Subscriber ' + QUOTENAME(@@SERVERNAME)  + ' '
  6454.     select @command = @command + '-SubscriberDB ' + QUOTENAME(db_name()) + ' '
  6455.     SELECT @command = @command + '-SubscriptionType ' + convert(nvarchar(10), @subscription_type_id)  + ' '
  6456.     
  6457.     select @command = @command + '-SubscriberSecurityMode ' + 
  6458.         convert(nvarchar(10),@subscriber_security_mode) + ' '
  6459.     if @subscriber_login is not NULL
  6460.         select @command = @command + '-SubscriberLogin ' + quotename(@subscriber_login) + ' '
  6461.     if @subscriber_password is not NULL
  6462.     begin
  6463.         set @subscriber_enc_password = @subscriber_password
  6464.         exec @retcode = master.dbo.xp_repl_encrypt @subscriber_enc_password OUTPUT
  6465.         select @command = @command + '-SubscriberEncryptedPassword ' + quotename(@subscriber_enc_password) + ' '
  6466.     end
  6467.     
  6468.     select @command = @command + @optional_command_line
  6469.     select @command = @command + '-Distributor ' + @distributor + ' '
  6470.     
  6471.     select @database = db_name()
  6472.  
  6473.     -- Get Merge category name (assumes category_id = 14)
  6474.     select @category_name = name FROM msdb.dbo.syscategories where category_id = 14
  6475.  
  6476. begin tran
  6477.     EXEC @retcode = dbo.sp_MSadd_repl_job
  6478.             @name = @name,
  6479.             @subsystem = 'Merge',
  6480.             @server = @@SERVERNAME,
  6481.             @databasename = @database,
  6482.             @enabled = 1,
  6483.             @freqtype = @frequency_type,
  6484.             @freqinterval = @frequency_interval,
  6485.             @freqsubtype = @frequency_subday,
  6486.             @freqsubinterval = @frequency_subday_interval,
  6487.             @freqrelativeinterval = @frequency_relative_interval,
  6488.             @freqrecurrencefactor = @frequency_recurrence_factor,
  6489.             @activestartdate = @active_start_date,
  6490.             @activeenddate = @active_end_date,
  6491.             @activestarttimeofday = @active_start_time_of_day,
  6492.             @activeendtimeofday = @active_end_time_of_day,
  6493.             @command = @command,
  6494.             @retryattempts = 10,
  6495.             @retrydelay = 1,
  6496.             @category_name = @category_name,
  6497.             @job_id = @merge_jobid OUTPUT
  6498.  
  6499.     if @@ERROR <> 0 or @retcode <> 0
  6500.         begin
  6501.             goto undo
  6502.         end
  6503.  
  6504.     if (@subscription_type_id = 1) OR (@subscription_type_id = 2)
  6505.     begin
  6506.         IF NOT EXISTS (select * from MSsubscription_properties 
  6507.             where UPPER(publisher) = UPPER(@publisher)
  6508.             and publisher_db =  @publisher_db
  6509.             and publication = @publication) 
  6510.         BEGIN
  6511.             
  6512.             IF (@encrypted_password = 0)
  6513.             -- Encrypt the password
  6514.             BEGIN
  6515.                 EXEC @retcode = master.dbo.xp_repl_encrypt @distributor_password OUTPUT
  6516.                 IF @@error <> 0 OR @retcode <> 0
  6517.                     return 1
  6518.             END
  6519.     
  6520.             IF (@publisher_encrypted_password = 0)
  6521.             -- Encrypt the password
  6522.             BEGIN
  6523.                 EXEC @retcode = master.dbo.xp_repl_encrypt @publisher_password OUTPUT
  6524.                 IF @@error <> 0 OR @retcode <> 0
  6525.                     return 1
  6526.             END
  6527.     
  6528.             INSERT INTO MSsubscription_properties 
  6529.             (publisher, publisher_db, publication, publication_type, 
  6530.              publisher_login,publisher_password, publisher_security_mode, 
  6531.              distributor, distributor_login, distributor_password, 
  6532.              distributor_security_mode, ftp_address, ftp_port, ftp_login, 
  6533.              ftp_password)
  6534.             values 
  6535.             (@publisher, @publisher_db, @publication, 2, @publisher_login, 
  6536.              @publisher_password, @publisher_security_mode, @distributor, 
  6537.              @distributor_login, @distributor_password, 
  6538.              @distributor_security_mode, @ftp_address, @ftp_port, @ftp_login,
  6539.              @ftp_password)
  6540.             IF @@ERROR <> 0 
  6541.             BEGIN
  6542.                 IF @@TRANCOUNT = 1
  6543.                     ROLLBACK TRAN
  6544.                 ELSE
  6545.                     COMMIT TRAN           
  6546.                 RETURN(1)
  6547.             END
  6548.         END
  6549.     end
  6550.  
  6551.         
  6552.     /* Update merge joibd for this pull subscription */
  6553.     UPDATE MSmerge_replinfo set merge_jobid = @merge_jobid WHERE repid = @repid
  6554.  
  6555.     /* Conditional support for MobileSync */
  6556.     if LOWER(@enabled_for_syncmgr) = 'true'
  6557.     BEGIN
  6558.         /* Call sp_MSregistersubscription so that the subscription can be synchronized via MobileSync etc. */
  6559.         exec @retcode = dbo.sp_MSregistersubscription @replication_type = 2,
  6560.                                     @publisher = @publisher,
  6561.                                     @publisher_db = @publisher_db,
  6562.                                     @publication = @publication,
  6563.                                     @subscriber = @subscriber,
  6564.                                     @subscriber_db = @subscriber_db,
  6565.                                     @subscriber_security_mode = @subscriber_security_mode,
  6566.                                     @subscriber_login = @subscriber_login,
  6567.                                     @subscriber_password = @subscriber_password,
  6568.                                     @distributor = @distributor,
  6569.                                     @subscription_id = @repid,
  6570.                                     @subscription_type = @subscription_type_id
  6571.  
  6572.         IF @@ERROR <> 0 or @retcode <> 0
  6573.         BEGIN
  6574.             goto undo
  6575.         END
  6576.     END
  6577.  
  6578. commit tran
  6579.     RETURN (0)
  6580. undo:
  6581.     IF @@TRANCOUNT = 1
  6582.         ROLLBACK TRAN
  6583.     ELSE COMMIT TRAN
  6584. GO
  6585.  
  6586. exec dbo.sp_MS_marksystemobject sp_addmergepullsubscription_agent
  6587. go
  6588.  
  6589. raiserror('Creating procedure sp_MSget_mergepullsubsagent_owner', 0,1)
  6590. GO
  6591. CREATE PROCEDURE sp_MSget_mergepullsubsagent_owner(
  6592.     @publication         sysname = NULL,                  /* Publication name */
  6593.     @publisher            sysname = NULL,              /* Publisher server */
  6594.     @publisher_db        sysname = NULL,              /* Publication database */
  6595.     @owner_sid          varbinary(85) OUTPUT
  6596.     )AS
  6597.     
  6598.     declare @srvid  int
  6599.     declare @pubid  uniqueidentifier 
  6600.     declare @subid  uniqueidentifier
  6601.     declare @job_id uniqueidentifier
  6602.     set nocount on
  6603.  
  6604.     select @owner_sid = NULL
  6605.  
  6606.     if exists (select * from sysobjects 
  6607.                where type = 'U' and
  6608.                      name = 'sysmergesubscriptions')
  6609.         -- Get the server id of the current server (subscriber)
  6610.     begin
  6611.         -- Get the srvid of the current subscriber database 
  6612.         select @srvid = srvid 
  6613.         from master.dbo.sysservers      
  6614.         where upper(@@servername) = upper(srvname)
  6615.  
  6616.         -- Get the pubid from sysmergepublications using @publisher, 
  6617.         -- @publisher_db, @publication 
  6618.         select @pubid = pubid
  6619.         from sysmergepublications
  6620.         where @publication = name
  6621.  
  6622.         -- Get the subid from sysmergesubscriptions using @pubid and @srvid
  6623.         select @subid = subid
  6624.         from sysmergesubscriptions
  6625.         where @pubid = pubid and
  6626.               @srvid = srvid and
  6627.               pubid <> subid 
  6628.  
  6629.         -- Get the merge_jobid from MSreplication_info using @subid
  6630.         select @job_id = merge_jobid
  6631.         from MSmerge_replinfo
  6632.         where @subid = repid
  6633.  
  6634.         -- Finally, get the owner_sid from msdb..sysjobs using @job_id
  6635.         select @owner_sid = owner_sid
  6636.         from msdb..sysjobs 
  6637.         where @job_id = job_id
  6638.     end
  6639. go
  6640.  
  6641. exec dbo.sp_MS_marksystemobject 'sp_MSget_mergepullsubsagent_owner'
  6642.  
  6643. raiserror('Creating procedure sp_dropmergepullsubscription', 0,1)
  6644. GO
  6645. CREATE PROCEDURE sp_dropmergepullsubscription(
  6646.     @publication         sysname = NULL,                  /* Publication name */
  6647.     @publisher            sysname = NULL,              /* Publisher server */
  6648.     @publisher_db        sysname = NULL,              /* Publication database */
  6649.     @reserved            bit = 0
  6650.     )AS
  6651.  
  6652.     SET NOCOUNT ON
  6653.  
  6654.     /*
  6655.     ** Declarations.
  6656.     */
  6657.  
  6658.     declare @retcode                 int
  6659.     declare @subscriber_srvid         int
  6660.     declare @publisher_srvid         int
  6661.     declare    @pubid                     uniqueidentifier
  6662.     declare    @subid                     uniqueidentifier
  6663.     declare    @partnerid                 uniqueidentifier 
  6664.     declare @local_server            sysname
  6665.     declare @local_db                sysname
  6666.     declare @merge_jobid             binary(16)
  6667.     declare @cmd                     nvarchar(255)
  6668.     declare @pubidstr                nvarchar(38)
  6669.     declare @subscriber                sysname
  6670.     declare @subscriber_db            sysname
  6671.     declare @subscriber_type        int
  6672.     declare @local_job                 bit
  6673.     declare @implicit_transaction    int
  6674.     declare @close_cursor_at_commit int
  6675.     declare @owner_sid              varbinary(85)
  6676.     declare @owner_name             sysname
  6677.     declare @qualified_publication_name nvarchar(512)
  6678.  
  6679.  
  6680.     select @close_cursor_at_commit = 0
  6681.     select @implicit_transaction = 0
  6682.  
  6683.     /*
  6684.     ** Get original setting values before setting them to false for recursive calling
  6685.     */
  6686.     IF (@reserved = 0)
  6687.     BEGIN
  6688.         SELECT @implicit_transaction = @@options & 2
  6689.         SELECT @close_cursor_at_commit = @@options & 4
  6690.         SET IMPLICIT_TRANSACTIONS OFF
  6691.         SET CURSOR_CLOSE_ON_COMMIT OFF
  6692.     END
  6693.  
  6694.     /* 
  6695.     ** Security Check.
  6696.     */
  6697.     exec @retcode = dbo.sp_MSreplcheck_subscribe
  6698.     if @@ERROR <> 0 or @retcode <> 0
  6699.         return(1)
  6700.  
  6701.      /*
  6702.     ** Initializations.
  6703.     */                
  6704.     set @local_db = DB_NAME()
  6705.     set @local_server = @@SERVERNAME
  6706.     set @subscriber = @@SERVERNAME     
  6707.     set @subscriber_db = DB_NAME()
  6708.  
  6709.    /*
  6710.     ** Assign parameter values appropriately
  6711.     */
  6712.             
  6713.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  6714.     IF @subscriber_srvid IS NULL
  6715.         BEGIN
  6716.            RAISERROR (14010, 16, -1)
  6717.            RETURN (1)     
  6718.         END
  6719.         
  6720.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  6721.         BEGIN
  6722.             RAISERROR (14055, 16, -1)
  6723.             RETURN (1)
  6724.         END        
  6725.  
  6726.     /*
  6727.     ** Parameter Check: @publisher
  6728.     ** Check to make sure that the publisher is defined
  6729.     */
  6730.             IF @publisher IS NULL
  6731.             BEGIN
  6732.                 RAISERROR (14043, 16, -1, '@publisher')
  6733.                 RETURN (1)
  6734.             END
  6735.  
  6736.             EXECUTE @retcode = dbo.sp_validname @publisher
  6737.             IF @@ERROR <> 0 OR @retcode <> 0
  6738.                RETURN (1)
  6739.  
  6740.     /*
  6741.     ** Parameter Check: @publisher_db
  6742.     */
  6743.             IF @publisher_db IS NULL
  6744.             BEGIN
  6745.                 RAISERROR (14043, 16, -1, '@publisher_db')
  6746.                 RETURN (1)
  6747.             END    
  6748.  
  6749.     /*
  6750.     ** Parameter Check:  @publication.
  6751.     ** If the publication name is specified, check to make sure that it
  6752.     ** conforms to the rules for identifiers and that the publication
  6753.     ** actually exists.  Disallow NULL.
  6754.     */
  6755.     if @publication IS NULL
  6756.         BEGIN
  6757.             RAISERROR (14043, 16, -1, '@publication')
  6758.             RETURN (1)
  6759.         END
  6760.  
  6761.     IF LOWER(@publication) = 'all'
  6762.         BEGIN
  6763.             declare hC1 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT name FROM sysmergepublications FOR READ ONLY
  6764.             
  6765.             OPEN hC1
  6766.             FETCH hC1 INTO @publication
  6767.             if @@fetch_status = -1 
  6768.                 begin
  6769.                     CLOSE hC1
  6770.                     DEALLOCATE hC1
  6771.                     RETURN (0) --- It's OK to have no publication when 'ALL'
  6772.                 end
  6773.             WHILE (@@fetch_status <> -1)
  6774.                 BEGIN
  6775.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  6776.                                       @publisher = @publisher,
  6777.                                       @publisher_db = @publisher_db,
  6778.                                       @reserved = 1
  6779.                     FETCH hC1 INTO @publication
  6780.                 END
  6781.             CLOSE hC1
  6782.             DEALLOCATE hC1
  6783.             RETURN (0)
  6784.         END
  6785.         
  6786.     IF LOWER(@publisher) = 'all'
  6787.         BEGIN
  6788.             declare hC4 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT srvname FROM master..sysservers FOR READ ONLY
  6789.             
  6790.             OPEN hC4
  6791.             FETCH hC4 INTO @publisher
  6792.             WHILE (@@fetch_status <> -1)
  6793.                 BEGIN
  6794.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  6795.                                                 @publisher = @publisher,
  6796.                                                 @publisher_db = @publisher_db,
  6797.                                                 @reserved = 1
  6798.                     FETCH hC4 INTO @publisher
  6799.                 END
  6800.             CLOSE hC4
  6801.             DEALLOCATE hC4
  6802.             RETURN (0)
  6803.         END
  6804.  
  6805.     /*
  6806.     ** Validate that the publisher is a valid server
  6807.     */
  6808.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  6809.     IF @publisher_srvid IS NULL
  6810.         BEGIN
  6811.             --RAISERROR (14010, 16, -1)
  6812.                RETURN (1)
  6813.         END
  6814.  
  6815.  
  6816.     /* Previously the condition is set as 'AND subid<>pubid' which is fatally errorous */
  6817.  
  6818.     IF LOWER(@publisher_db) = 'all'
  6819.         BEGIN
  6820.             declare hC5 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT db_name FROM sysmergesubscriptions 
  6821.                     WHERE subid = pubid and pubid in (select pubid from sysmergepublications 
  6822.                             where UPPER(publisher)=UPPER(@publisher) 
  6823.                                 and name=@publication)
  6824.                                 
  6825.                         FOR READ ONLY
  6826.             
  6827.             OPEN hC5
  6828.             FETCH hC5 INTO @publisher_db
  6829.             WHILE (@@fetch_status <> -1)
  6830.                 BEGIN
  6831.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  6832.                                       @publisher = @publisher,
  6833.                                       @publisher_db = @publisher_db,
  6834.                                       @reserved = 1
  6835.                     FETCH hC5 INTO @publisher_db
  6836.                 END
  6837.             CLOSE hC5
  6838.             DEALLOCATE hC5
  6839.             RETURN (0)
  6840.         END
  6841.  
  6842.     /*
  6843.     ** return error if only there is no 'ALL'. Same is true for the rest of error handling.
  6844.     */
  6845.     if NOT EXISTS (select * FROM sysmergepublications 
  6846.     WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db) 
  6847.     BEGIN
  6848.         if @reserved = 0
  6849.             RAISERROR (20026, 16, -1, @publication)
  6850.         RETURN (1)
  6851.     END
  6852.         
  6853.     select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  6854.     set @pubidstr = '''' + convert(nchar(36), @pubid) + ''''
  6855.     if @pubid is null  
  6856.         BEGIN
  6857.             if @reserved = 0
  6858.                 RAISERROR (20026, 16, -1, @publication)
  6859.                RETURN (1)
  6860.         END
  6861.  
  6862.     /*
  6863.     ** Only members of the sysadmin group and the creator of the distribution
  6864.     ** agent can drop a pull subscription successfully. This behavior matches 
  6865.     ** the behavior of the sysjobs_view. DBO of the subscriber database, 
  6866.     ** sysadmins (owner is undefined) can drop a subscription if the owner_sid 
  6867.     ** is null.
  6868.     */
  6869.     
  6870.     EXEC sp_MSget_mergepullsubsagent_owner @publisher = @publisher,
  6871.                                            @publisher_db = @publisher_db,
  6872.                                            @publication = @publication,
  6873.                                            @owner_sid = @owner_sid OUTPUT 
  6874.     
  6875.     IF (@owner_sid is not null AND
  6876.         (SUSER_SID() <> @owner_sid) AND
  6877.         (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0))
  6878.     BEGIN
  6879.         SELECT @owner_name = SUSER_SNAME(@owner_sid)
  6880.         SELECT @qualified_publication_name = @publisher + N':' + 
  6881.                                              @publisher_db + N':' +
  6882.                                              @publication
  6883.         RAISERROR(21121,16,-1,@owner_name, @qualified_publication_name) 
  6884.         RETURN (1)
  6885.     END
  6886.  
  6887.     /*
  6888.     ** Get subscriptions from either local replicas or global replicas
  6889.     */
  6890.     select @subid = subs1.subid, @subscriber_type = subs1.subscriber_type, @partnerid = subs2.subid from
  6891.         sysmergesubscriptions     subs1,
  6892.           sysmergesubscriptions     subs2,
  6893.         sysmergepublications         pubs
  6894.         where subs1.srvid = @subscriber_srvid
  6895.             and subs1.db_name = @subscriber_db
  6896.             and subs2.srvid = @publisher_srvid
  6897.             and subs2.db_name = @publisher_db
  6898.             and subs1.pubid = subs2.subid
  6899.             and subs2.pubid = pubs.pubid
  6900.             and pubs.name = @publication
  6901.             and UPPER(pubs.publisher)=UPPER(@publisher)
  6902.             and pubs.publisher_db=@publisher_db
  6903.  
  6904.     if @subid IS NULL 
  6905.          begin
  6906.             if @reserved = 0 
  6907.                 raiserror (14050, 16, -1)
  6908.              RETURN (0)
  6909.         end                 
  6910.  
  6911.     begin tran
  6912.     save TRAN dropmergepullsubscription
  6913.     
  6914.         /*     
  6915.         ** Drop the local merge task
  6916.         */
  6917.         select @merge_jobid = merge_jobid from MSmerge_replinfo WHERE repid = @subid
  6918.         if (@merge_jobid IS NOT NULL)
  6919.         BEGIN
  6920.             IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @merge_jobid)
  6921.             BEGIN
  6922.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @merge_jobid
  6923.                 IF @@ERROR <> 0 or @retcode <> 0
  6924.                     GOTO FAILURE
  6925.             END
  6926.         END                                    
  6927.  
  6928.         if @subid <> @partnerid
  6929.         BEGIN
  6930.             DELETE MSmerge_replinfo WHERE repid = @subid 
  6931.             IF @@ERROR <> 0
  6932.                 GOTO FAILURE
  6933.             delete from sysmergesubscriptions where subid = @subid
  6934.             if @@ERROR <> 0
  6935.                 GOTO FAILURE
  6936.  
  6937.             /* Call sp_MSunregistersubscription so that the reg entries get deleted */
  6938.             exec @retcode = dbo.sp_MSunregistersubscription @publisher = @publisher,
  6939.                                         @publisher_db = @publisher_db,
  6940.                                         @publication = @publication,
  6941.                                         @subscriber = @@SERVERNAME,
  6942.                                         @subscriber_db = @subscriber_db
  6943.             IF @retcode<>0 or @@ERROR<>0
  6944.                 GOTO FAILURE
  6945.  
  6946.             exec dbo.sp_MSpublicationcleanup @publisher=@publisher, 
  6947.                                             @publisher_db = @publisher_db,
  6948.                                             @publication = @publication
  6949.             IF @@ERROR <> 0 
  6950.                 BEGIN
  6951.                     RAISERROR (20025, 16, -1, @publication)
  6952.                     GOTO FAILURE
  6953.                 END
  6954.         END
  6955.         
  6956.         IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties')
  6957.         BEGIN
  6958.             DELETE FROM MSsubscription_properties 
  6959.             WHERE UPPER(publisher) = UPPER(@publisher)    AND
  6960.             publisher_db  = @publisher_db AND
  6961.             publication = @publication 
  6962.     
  6963.             IF @@ERROR <> 0 
  6964.                 GOTO FAILURE
  6965.     
  6966.             IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  6967.             BEGIN
  6968.                 DROP TABLE MSsubscription_properties
  6969.                 IF @@ERROR <> 0 
  6970.                     GOTO FAILURE
  6971.             END
  6972.         END
  6973.  
  6974.         /* 
  6975.         ** If last subscription is dropped and the DB is not enabled for publishing,
  6976.         ** then remove the merge system tables
  6977.         */
  6978.         IF (not exists (select * from sysmergesubscriptions )) 
  6979.             AND (select category & 4 FROM master..sysdatabases WHERE name = DB_NAME())=0
  6980.         BEGIN
  6981.                 execute @retcode = dbo.sp_MSdrop_mergesystables
  6982.                 if @@ERROR <> 0 or @retcode <> 0
  6983.                     begin
  6984.                         return (1)
  6985.                     end
  6986.         END    
  6987.     COMMIT TRAN
  6988.     /*
  6989.     ** Set back original settings
  6990.     */
  6991.     IF @reserved = 0
  6992.     BEGIN
  6993.         IF @implicit_transaction <>0 
  6994.             SET IMPLICIT_TRANSACTIONS ON
  6995.         IF @close_cursor_at_commit <>0 
  6996.             SET CURSOR_CLOSE_ON_COMMIT ON
  6997.     END
  6998.  
  6999.     RETURN(0)        
  7000.  
  7001. FAILURE:
  7002.     RAISERROR (14056, 16, -1)
  7003.     if @@trancount > 0
  7004.     begin
  7005.         ROLLBACK TRANSACTION dropmergepullsubscription
  7006.         COMMIT TRANSACTION
  7007.     end
  7008.     /*
  7009.     ** Set back original settings
  7010.     */    
  7011.     IF @reserved = 0
  7012.     BEGIN
  7013.         IF @implicit_transaction <>0 
  7014.             SET IMPLICIT_TRANSACTIONS ON
  7015.         IF @close_cursor_at_commit <>0 
  7016.             SET CURSOR_CLOSE_ON_COMMIT ON
  7017.     END
  7018.     return 1
  7019. go
  7020. exec dbo.sp_MS_marksystemobject sp_dropmergepullsubscription
  7021. go
  7022.  
  7023. grant execute on dbo.sp_dropmergepullsubscription to public
  7024. go
  7025.  
  7026. -- synctran supporting sprocs
  7027. raiserror('Creating procedure sp_MSreplraiserror', 0,1)
  7028. go
  7029.  
  7030. create proc sp_MSreplraiserror @errorid int, @param1 sysname = null, @param2 sysname= null
  7031. as
  7032.     if @errorid = 20508 raiserror (20508, 16, 1)
  7033.     else if @errorid = 20509 raiserror (20509, 16, 1)
  7034.     else if @errorid = 20510 raiserror (20510, 16, 1)
  7035.     else if @errorid = 20511 raiserror (20511, 16, 1)
  7036.     else if @errorid = 20512 raiserror (20512, 16, 1)
  7037.     else if @errorid = 20515 raiserror (20515, 16, 1)
  7038.     else if @errorid = 20516 raiserror (20516, 16, 1)
  7039.     else if @errorid = 20517 raiserror (20517, 16, 1)
  7040.     else if @errorid = 20518 raiserror (20518, 16, 1)
  7041.     else if @errorid = 20519 raiserror (20519, 16, 1)
  7042.     else if @errorid = 20520 raiserror (20520, 16, 1)
  7043.     else if @errorid = 21034 raiserror (21034, 16, 1)
  7044.     else if @errorid = 21054 raiserror (21054, 16, 1)
  7045.     else if @errorid = 21161 raiserror (21161, 16, 1)
  7046. go
  7047.  
  7048. raiserror('Creating procedure sp_check_sync_trigger', 0,1)
  7049. go
  7050.  
  7051. create proc sp_check_sync_trigger @trigger_procid int, @trigger_op char(10) OUTPUT
  7052. as
  7053.  
  7054.     select @trigger_op = NULL
  7055.  
  7056. -- debug
  7057. --    select 'Entered sp_check_synctrigger', 'calling trigger' = object_name(@trigger_procid)
  7058. -- debug
  7059.  
  7060.     declare @trigid int
  7061.  
  7062.     select @trigid = so1.id from sysobjects so1, sysobjects so2 where
  7063.     so1.type = N'TR' and so1.name like N'trg_MSsync_ins_%' and so1.parent_obj = so2.parent_obj
  7064.     and so2.id = @trigger_procid
  7065.     
  7066.     -- if nestlevel of insert trigger on same table > 0 then bail
  7067.  
  7068.     if trigger_nestlevel( @trigid ) > 0
  7069.     begin
  7070. -- debug
  7071. --        select 'sp_check_synctrigger: synctran insert trigger is active, so do nothing'
  7072. -- debug
  7073.          return 1
  7074.     end
  7075.     else
  7076.         return 0
  7077. go
  7078.  
  7079. raiserror('Creating procedure sp_check_for_sync_trigger', 0,1)
  7080. go
  7081.  
  7082. create proc sp_check_for_sync_trigger @tabid int, @trigger_op char(10) = NULL OUTPUT
  7083. as
  7084.  
  7085.     select @trigger_op = NULL
  7086.  
  7087. -- debug
  7088. --    select 'Entered sp_check_for_sync_trigger', 'calling trigger' = object_name(@trigger_procid)
  7089. -- debug
  7090.  
  7091.     declare @ins_trigid int
  7092.     declare @upd_trigid int
  7093.     declare @del_trigid int
  7094.  
  7095.     select @ins_trigid = id from sysobjects where
  7096.         type = N'TR' and name like N'trg_MSsync_ins_%' and parent_obj = @tabid
  7097.     select @upd_trigid = id from sysobjects where
  7098.         type = N'TR' and name like N'trg_MSsync_upd_%' and parent_obj = @tabid
  7099.     select @del_trigid = id from sysobjects where
  7100.         type = N'TR' and name like N'trg_MSsync_del_%' and parent_obj = @tabid
  7101.  
  7102.     if trigger_nestlevel( @ins_trigid ) > 0
  7103.     begin
  7104. -- debug
  7105. --     select 'sp_check_for_sync_trigger: synctran insert trigger is active'
  7106. -- debug
  7107.          select @trigger_op = 'ins'
  7108.          return 1
  7109.     end
  7110.     else    -- if nestlevel of insert trigger on same table > 0 then bail
  7111.     if trigger_nestlevel( @upd_trigid ) > 0
  7112.     begin
  7113. -- debug
  7114. --     select 'sp_check_for_sync_trigger: synctran update trigger is active'
  7115. -- debug
  7116.          select @trigger_op = 'upd'
  7117.          return 1
  7118.     end
  7119.     else
  7120.     if trigger_nestlevel( @del_trigid ) > 0
  7121.     begin
  7122. -- debug
  7123. --     select 'sp_check_for_sync_trigger: synctran update trigger is active'
  7124. -- debug
  7125.          select @trigger_op = 'del'
  7126.          return 1
  7127.     end
  7128.     else
  7129.         return 0
  7130. go
  7131.  
  7132. raiserror('Creating procedure sp_MSpad_command', 0,1)
  7133. go
  7134. create proc sp_MSpad_command
  7135.     @cmd     nvarchar(4000) output,
  7136.     @indent  int = 0  -- indent for command buffer (for pretty formatting
  7137. as
  7138.     declare @cnt int
  7139.  
  7140.     select @cmd = N''
  7141.     select @cnt = 0
  7142.  
  7143.     while (@cnt < @indent)
  7144.     begin
  7145.         select @cmd = @cmd + N' '
  7146.         select @cnt = @cnt + 1
  7147.     end
  7148. go
  7149.  
  7150. raiserror('Creating procedure sp_MSflush_command', 0,1)
  7151. go
  7152. create proc sp_MSflush_command
  7153.     @cmd     nvarchar(4000) output,
  7154.     @force   int,     -- 0 = flush if necesssary, 1 = flush always
  7155.     @indent  int = 0  -- indent for command buffer (for pretty formatting
  7156. as
  7157. -- debug
  7158. --    if len(@cmd) >= 4000
  7159. --    begin
  7160. --        raiserror("buffer overflow!", 16, 1)
  7161. --        select @cmd
  7162. --    end
  7163. -- debug
  7164.  
  7165.     if @force = 1 or len( @cmd ) > 3000
  7166.     begin
  7167.         insert into #proctext(procedure_text) values( @cmd )
  7168.         select @cmd = N''
  7169.         if @indent > 0 
  7170.             exec dbo.sp_MSpad_command @cmd output, @indent
  7171.     end
  7172. go
  7173.  
  7174.  
  7175.  
  7176. raiserror('Creating procedure sp_MSget_colinfo', 0,1)
  7177. go
  7178. create proc sp_MSget_colinfo 
  7179.     @objid int,
  7180.     @colid int, 
  7181.     @columns binary(32), 
  7182.     @bGetTextImageInfo tinyint = 0, -- boolean for returning text/image info
  7183.     @colname sysname output, 
  7184.     @ccoltype sysname output
  7185. as
  7186.     declare @isset        int
  7187.  
  7188.     if @columns is not NULL
  7189.         -- this code path for synctran procs
  7190.         exec @isset = dbo.sp_isarticlecolbitset @colid, @columns
  7191.     else
  7192.         -- this code path for synctran triggers
  7193.         select @isset = 1
  7194.  
  7195.     if @isset != 0 
  7196.     begin
  7197.         select @colname = c.name, @ccoltype= t.name from syscolumns c, systypes t
  7198.         where id = @objid and colid = @colid and c.xtype = t.xusertype
  7199.         -- when checking replicated columns, text/image datatypes cannot be declared or used locally
  7200.         if (@bGetTextImageInfo = 0) and (@ccoltype in (N'text',N'ntext',N'image'))
  7201.             return 1
  7202.     end
  7203.     else
  7204.     begin
  7205.         select @colname = null, @ccoltype = null
  7206.         return 1
  7207.     end
  7208.  
  7209.     return 0
  7210. go
  7211.  
  7212. raiserror('Creating procedure sp_MSget_col_position ', 0,1)
  7213. go
  7214. create procedure sp_MSget_col_position 
  7215.     @objid int,
  7216.     @columns binary(32),
  7217.     @key     sysname, 
  7218.     @colpos  sysname output,
  7219.     @art_col int = NULL output,
  7220.     @get_num_col bit = 0,
  7221.     @num_col  int = NULL output,
  7222.     @this_col int = null output
  7223. as
  7224.   
  7225.     declare @colname      sysname
  7226.     declare @ccoltype     sysname
  7227.     declare @src_cols     int
  7228.     declare @rc           int
  7229.     
  7230.     select @src_cols = count(*) from syscolumns where id = @objid
  7231.     select @this_col = 1
  7232.  
  7233.     select @num_col = 0
  7234.  
  7235.     
  7236.     while @this_col <= @src_cols 
  7237.     begin
  7238.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 1, @colname output, @ccoltype output
  7239.         if @rc = 0
  7240.         begin
  7241.             set @num_col = @num_col + 1
  7242.             -- If @get_num_col is 1, we just need the number of columns in the partition.
  7243.             if @get_num_col = 0 and @colname = @key
  7244.             begin
  7245.                 select @colpos = 'c' + convert(varchar(4), @this_col)
  7246.                 set @art_col = @num_col
  7247.                 break
  7248.             end
  7249.         end
  7250.         set @this_col = @this_col + 1
  7251.     end
  7252.     return 0
  7253. go
  7254.  
  7255. raiserror('Creating procedure sp_MSget_type', 0,1)
  7256. go
  7257. create proc sp_MSget_type 
  7258.     @tabid int, 
  7259.     @colid int, 
  7260.     @colname sysname output, 
  7261.     @typestring nvarchar(4000) output
  7262. as
  7263.     declare @ccolchar       nvarchar(5)
  7264.     declare @coltype        tinyint
  7265.     declare @prec           smallint
  7266.     declare @scale          int
  7267.     declare @ccoltype       sysname
  7268.     declare @xtype          int
  7269.  
  7270.     select @colname = c.name, @xtype = c.xtype, @prec = c.prec, @scale = c.scale,
  7271.         @ccoltype = t.name
  7272.     from syscolumns c, systypes t
  7273.     where c.id = @tabid and c.colid = @colid and 
  7274.         c.xtype = t.xusertype
  7275.      
  7276.     select @typestring = @ccoltype
  7277.  
  7278.     -- datatypes requiring precision (nchar, nvarchar, binary, varbinary)
  7279.     -- format: @var <dt> (prec)
  7280.     if @ccoltype in (N'char',N'nchar', N'varchar', N'nvarchar', N'binary', N'varbinary') 
  7281.         select @typestring = @typestring + N'(' + rtrim(convert(nchar(10),@prec)) + N')'
  7282.  
  7283.     -- datatypes requiring precision & scale (numeric & decimal)
  7284.     -- format: @var <dt> (prec, scale)
  7285.     else if @ccoltype in (N'numeric', N'decimal') 
  7286.         select @typestring = @typestring + N'(' + rtrim(convert(nchar(10),ColumnProperty(@tabid, @colname, 'PRECISION'))) + N',' + 
  7287.             rtrim(convert(nchar(10),@scale)) + N')'
  7288.     
  7289.     -- text/image datatypes cannot be declared or used locally
  7290.     else if @ccoltype in (N'text',N'ntext',N'image')
  7291.         select  @typestring = NULL
  7292. go
  7293.  
  7294. raiserror('Creating procedure sp_MSscript_where_clause', 0,1)
  7295. go
  7296. create procedure sp_MSscript_where_clause
  7297.     @objid          int,
  7298.     @columns      binary(32), 
  7299.     @clause_type  varchar(6) = 'pk_new', -- 'new pk', 'old pk', 'upd ts', 'upd rc', 'trg pk'
  7300.     @ts_col       sysname = NULL,
  7301.     @indent       int = 0,
  7302.     @op_type      char(3) = NULL -- 'ins', 'del'
  7303. as
  7304.     declare @cmd          nvarchar(4000)
  7305.     declare @colname      sysname
  7306.     declare @ccoltype     sysname
  7307.     declare @spacer       nvarchar(20)
  7308.     declare @indkey       int
  7309.     declare @indid        int
  7310.     declare @key          sysname
  7311.     declare @rc           int
  7312.     declare @this_col     int
  7313.     declare @art_col      int
  7314.     declare @src_cols     int
  7315.     declare @col          sysname
  7316.     declare @qualname     nvarchar(512)
  7317.  
  7318.     select @spacer = N' ', @cmd = N''
  7319.     select @indkey = 1, @indid = 0
  7320.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  7321.     select @src_cols = count(*) from syscolumns where id = @objid
  7322.     exec dbo.sp_MSpad_command @cmd output, @indent
  7323.     select @cmd = @cmd + N'where'
  7324.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  7325.  
  7326.     if @clause_type in ('new pk', 'old pk', 'upd ts', 'trg pk')
  7327.     begin
  7328.         exec @indid = dbo.sp_MStable_has_unique_index @objid
  7329.  
  7330.         if @indid > 0
  7331.         begin
  7332.             while @indkey < 16 and index_col(@qualname, @indid, @indkey) is not null
  7333.             begin
  7334.                 select @key = index_col(@qualname, @indid, @indkey)
  7335.                 --exec dbo.sp_MSget_col_position @objid, @columns, @key, @col output, @this_col output
  7336.                 exec dbo.sp_MSget_col_position @objid, @columns, @key, @col output, NULL, 0, NULL, @this_col output
  7337.         
  7338.                 if @clause_type = 'new pk'
  7339.                 begin
  7340.                     if ColumnProperty(@objid, @key, 'IsIdentity') = 1
  7341.                         select @cmd = @cmd + @spacer + quotename(@key) + N' = @@identity'
  7342.                     else
  7343.                         select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col
  7344.  
  7345.                     select @spacer = ' and
  7346.          '
  7347.                 end
  7348.                 else if @clause_type = 'upd ts'
  7349.                 begin
  7350.                     select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col + N'_old'
  7351.                     select @spacer = ' and
  7352.          '
  7353.                 end
  7354.                 else if @clause_type in ('trg pk', 'old pk')
  7355.                 begin
  7356.                     if @op_type = 'ins'
  7357.                         select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col + N'_old'
  7358.                     else
  7359.                         -- The vars correspoding to pk were set in sp_MSscript
  7360.                         -- _pkvar_assignment.
  7361.                         select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col 
  7362.  
  7363.                     select @spacer = ' and
  7364.          '
  7365.                 end
  7366.  
  7367.                 select @indkey = @indkey + 1
  7368.                 
  7369.                 -- flush command if necessary
  7370.                 exec dbo.sp_MSflush_command @cmd output, 0, @indent
  7371.             end
  7372.         end
  7373.  
  7374.         -- if clause_type is 'upd ts', add timestamp col
  7375.         if @clause_type = 'upd ts'
  7376.         begin
  7377.             exec dbo.sp_MSget_col_position @objid, @columns, @ts_col, @col output
  7378.             select @cmd = @cmd + @spacer + @ts_col + N' = @' + @col + N'_old'
  7379.         end
  7380.  
  7381.         -- save off command fragment
  7382.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  7383.     end
  7384.     else if @clause_type = 'upd rc'
  7385.     begin
  7386.         select @this_col = 1, @art_col = 1
  7387.  
  7388.         while @this_col <= @src_cols
  7389.         begin
  7390.             exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @colname output, @ccoltype output
  7391.             if @rc = 0
  7392.             begin
  7393.                 select @cmd = @cmd +  @spacer + '(' + @colname + N' = @c' + convert(varchar(4), @this_col) + N'_old or (' 
  7394.                 select @cmd = @cmd + @colname + ' is null and @c' + convert(varchar(4), @this_col) + N'_old is null)) '
  7395.                 select @spacer = N' and 
  7396.      '
  7397.                 exec dbo.sp_MSflush_command @cmd output, 0, @indent
  7398.             end
  7399.  
  7400.             exec dbo.sp_MSflush_command @cmd output, 1, @indent
  7401.  
  7402.             select @this_col = @this_col + 1
  7403.         end
  7404.  
  7405.         -- save off cmd fragment
  7406.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  7407.     end
  7408. go
  7409.  
  7410. raiserror('Creating procedure sp_MSscript_params', 0,1)
  7411. go
  7412. create procedure sp_MSscript_params
  7413.     @objid   int,
  7414.     @columns binary(32),
  7415.     @postfix nvarchar(8) = NULL,
  7416.     @bOutParams tinyint = 0, -- boolean indicating wether or not to declare timestamp/identity params as output params
  7417.     @outvars nvarchar(4000) = NULL output
  7418. as
  7419.     declare @cmd          nvarchar(4000)
  7420.     declare @colname      sysname
  7421.     declare @typestring   nvarchar(4000)
  7422.     declare @spacer       nvarchar(1)
  7423.     declare @spacer2      nvarchar(1)
  7424.     declare @src_cols     int
  7425.     declare @this_col     int
  7426.     declare @art_col      int
  7427.     declare @isset        int
  7428.  
  7429.     select @spacer = N' '        
  7430.     select @spacer2 = N' '
  7431.     select @this_col = 1
  7432.     select @art_col = 1
  7433.     select @src_cols = count(*) from syscolumns where id = @objid
  7434.     select @outvars = null
  7435.     select @cmd = N''
  7436.  
  7437.     while @this_col <= @src_cols
  7438.     begin
  7439.         if @columns is not null
  7440.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  7441.         else
  7442.             select @isset = 1
  7443.  
  7444.         if @isset != 0 and EXISTS (select name from syscolumns where id=@objid and colid=@this_col and iscomputed<>1) 
  7445.         begin
  7446.             exec dbo.sp_MSget_type @objid, @this_col, @colname output, @typestring OUTPUT
  7447.             if @typestring != NULL
  7448.             begin
  7449.                 if @postfix is null
  7450.                     select @cmd = @cmd + @spacer + N'@c' + convert(varchar(4), @this_col) + N' ' + @typestring 
  7451.                 else
  7452.                     -- old vars
  7453.                     select @cmd = @cmd + @spacer + N'@c' + convert(varchar(4), @this_col) + @postfix + N' ' + @typestring
  7454.  
  7455.                 -- new vars of type timestamp and identity are declared as output params
  7456.                 if @bOutParams = 1 and (@typestring = N'timestamp' or ColumnProperty(@objid, @colname, 'IsIdentity') = 1)
  7457.                 begin
  7458.                     select @cmd = @cmd + N' output'
  7459.                     select @outvars = isnull(@outvars, N'') + @spacer2 + N'@c' + convert(varchar(4), @this_col) + N' = ' + @colname 
  7460.                     select @spacer2 = N','
  7461.                 end
  7462.                 
  7463.                 select @spacer = N','
  7464.             end
  7465.             select @art_col = @art_col + 1
  7466.  
  7467.             -- flush command if necessary
  7468.             exec dbo.sp_MSflush_command @cmd output, 0
  7469.        end
  7470.        select @this_col = @this_col + 1
  7471.     end
  7472.  
  7473.     -- save off cmd fragment
  7474.     exec dbo.sp_MSflush_command @cmd output, 1
  7475. go
  7476.  
  7477. raiserror('Creating procedure sp_MSscript_begintrig1', 0,1)
  7478. go
  7479. create procedure sp_MSscript_begintrig1
  7480.     @trigname      sysname,
  7481.     @objid         int,
  7482.     @procname      sysname,
  7483.     @filter_clause nvarchar(4000),
  7484.     @op_type       char(3) = 'ins' -- ins, upd, del
  7485. as
  7486.     declare @cmd       nvarchar(4000)
  7487.     declare @start     int
  7488.     declare @sub_len   int
  7489.     declare @qualname  nvarchar(512)
  7490.  
  7491.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  7492.  
  7493.     -- construct trigger name
  7494.     select @cmd = N'create trigger ' + QUOTENAME(@trigname) + N' on ' + @qualname + N' '
  7495.  
  7496.     if @op_type = 'ins'
  7497.         select @cmd = @cmd + N'for insert not for replication 
  7498.  as 
  7499. '
  7500.     else if @op_type = 'upd'
  7501.         select @cmd = @cmd + N'for update not for replication 
  7502.  as
  7503. '
  7504.     else if @op_type = 'del'
  7505.         select @cmd = @cmd + N'for delete not for replication 
  7506.  as
  7507. '
  7508.  
  7509.     exec dbo.sp_MSflush_command @cmd output, 1
  7510.  
  7511.  
  7512.     -- declare common local variables
  7513.     insert into #proctext(procedure_text) values 
  7514.         (N'declare @rc int, @retcode int, @connect_string nvarchar(2000), @rpc_proc nvarchar(4000), 
  7515. ')
  7516.     insert into #proctext(procedure_text) values 
  7517.         (N'@rpc_types nvarchar(4000), @bitmap varbinary(4000)
  7518. ')
  7519.  
  7520.     -- script variables used to retrieve data from inserted table
  7521.     if @op_type in ('ins', 'upd')
  7522.     begin
  7523.         insert into #proctext(procedure_text) values(N'declare ')
  7524.         exec dbo.sp_MSscript_params @objid, null, null, 0, null
  7525.         insert into #proctext(procedure_text) values(N' 
  7526. ')
  7527.     end
  7528.     insert into #proctext(procedure_text) values(N'declare ')
  7529.     exec dbo.sp_MSscript_params @objid, null, '_old',  0, null
  7530.  
  7531.     insert into #proctext(procedure_text) values(N' 
  7532.  
  7533. ')
  7534.     insert into #proctext(procedure_text) values(N'select @rc = @@ROWCOUNT 
  7535.  
  7536. ')
  7537.         
  7538.     -- Optimization. Return immediately if no row changed
  7539.     -- This must be at the beginning of the trigger to @@rowcount be overwritten.
  7540.     insert into #proctext(procedure_text) values(N'if @rc = 0 return 
  7541.  
  7542. ')
  7543.         
  7544.  
  7545.     insert into #proctext(procedure_text) values(N'select @bitmap = columns_updated()
  7546.  
  7547. ')
  7548.  
  7549.     -- Partition check statement
  7550.     if @filter_clause IS NOT NULL
  7551.     begin
  7552.         insert into #proctext(procedure_text) values (N'if exists (select * from inserted where not (')
  7553.         
  7554.         -- break filter_clause into chunks of 255
  7555.         select @start = 1
  7556.         while @start < len(@filter_clause)
  7557.         begin
  7558.             if len(@filter_clause) < 255
  7559.                 select @sub_len = len(@filter_clause)
  7560.             else
  7561.                 select @sub_len = 255
  7562.             select @cmd = substring(@filter_clause, @start, @sub_len)
  7563.             exec dbo.sp_MSflush_command @cmd output, 1
  7564.             select @start = @start + @sub_len
  7565.         end
  7566.             
  7567.         insert into #proctext(procedure_text) values (N')) 
  7568.  begin 
  7569.      exec sp_MSreplraiserror 21034
  7570.      goto FAILURE 
  7571.  end
  7572. ')
  7573.     end
  7574. go
  7575.  
  7576. raiserror('Creating procedure sp_MSscript_begintrig2', 0,1)
  7577. go
  7578. create procedure sp_MSscript_begintrig2
  7579.     @objid       int, 
  7580.     @op_type     char(3) = 'ins' -- ins, upd, del
  7581. as
  7582.     declare @cmd nvarchar(4000)
  7583.  
  7584.     --select @cmd = N'if Objectproperty(@@procid, '
  7585.     if @op_type = 'ins' 
  7586.     insert into #proctext(procedure_text) values(N'if Objectproperty(@@procid,''TriggerInsertOrder'') != 1
  7587.  begin
  7588.      raiserror (21128, 16, 1)
  7589.      return 
  7590.  end
  7591.  
  7592. ')
  7593.  
  7594.     else if @op_type = 'upd' 
  7595.     insert into #proctext(procedure_text) values(N'if Objectproperty(@@procid,''TriggerUpdate'') != 1
  7596.  begin
  7597.      raiserror (21129, 16, 1)
  7598.      return 
  7599.  end
  7600.  
  7601. ')
  7602.  
  7603.     else if @op_type = 'del' 
  7604.     insert into #proctext(procedure_text) values(N'if Objectproperty(@@procid,''TriggerDeleteOrder'') != 1
  7605.  begin
  7606.      raiserror (21130, 16, 1)
  7607.      return 
  7608.  end
  7609.  
  7610. ')
  7611.  
  7612.  
  7613. -- debug
  7614. --    insert into #proctext(procedure_text) values(N' ')
  7615. --    if @op_type = 'ins'
  7616. --        insert into #proctext(procedure_text) 
  7617. --            values(N'select ''SyncTran Insert Trigger fired on table'' = ' + N'''' + @source_table + N'''')
  7618. --    else if @op_type = 'upd'
  7619. --        insert into #proctext(procedure_text) 
  7620. --            values(N'select ''SyncTran Update Trigger fired on table'' = ' + N'''' + @source_table + N'''')
  7621. --    else if @op_type = 'del'
  7622. --        insert into #proctext(procedure_text) 
  7623. --            values(N'select ''SyncTran Delete Trigger fired on table'' = ' + N'''' + @source_table + N'''')
  7624.  
  7625. --    insert into #proctext(procedure_text) values(N'    , ''global nestlevel'' = trigger_nestlevel() ') 
  7626. --    insert into #proctext(procedure_text) values(N'    , ''local nestlevel'' = trigger_nestlevel(@@procid) ')
  7627.  
  7628. --    if @op_type = 'ins'
  7629. --        insert into #proctext(procedure_text) values(N'    , ''fire_order'' = Objectproperty(@@procid, ''TriggerInsertOrder'') ')
  7630. --    if @op_type = 'upd'
  7631. --        insert into #proctext(procedure_text) values(N'    , ''fire_order'' = Objectproperty(@@procid, ''TriggerUpdateOrder'') ')
  7632. --    if @op_type = 'del'
  7633. --        insert into #proctext(procedure_text) values(N'    , ''fire_order'' = Objectproperty(@@procid, ''TriggerDeleteOrder'') ')    
  7634. -- debug
  7635.  
  7636.     -- Get rpc prefix
  7637.     -- Get rpc prefix
  7638.     insert into #proctext(procedure_text) values
  7639.         (N'exec @retcode = dbo.sp_MSget_publisher_rpc @@procid, @connect_string output
  7640.  if @retcode <>0 or @@error <> 0 goto FAILURE
  7641.  
  7642. ')
  7643.  
  7644.     insert into #proctext(procedure_text) values(N'BEGIN DISTRIBUTED TRAN
  7645.  
  7646. ') 
  7647. go
  7648.  
  7649. raiserror('Creating procedure sp_MSscript_endtrig', 0,1)
  7650. go
  7651. create proc sp_MSscript_endtrig
  7652. as
  7653.     declare @cmd nvarchar(4000)
  7654.  
  7655.     insert into #proctext(procedure_text) values(N'if @@trancount > 0 commit tran return
  7656.  
  7657. ') 
  7658.    
  7659.     insert into #proctext(procedure_text) values(N'FAILURE: 
  7660.  if @@trancount > 0
  7661.  begin
  7662.      exec sp_MSreplraiserror 20512
  7663.      rollback tran
  7664.  end
  7665. ') 
  7666. go
  7667.  
  7668. raiserror('Creating procedure sp_MSscript_trigger_variables', 0,1)
  7669. go
  7670.  
  7671. create procedure sp_MSscript_trigger_variables
  7672.     @objid int,
  7673.     @prefix char(1) = null, -- null or '@'
  7674.     @postfix varchar(4) = null,
  7675.     @indent int = 0,
  7676.     @spacer nvarchar(1) = N' ', 
  7677.     @bOutput_params tinyint = 0,  -- declare output params if necessary
  7678.     @identity_col sysname = null,
  7679.     @ts_col sysname = null,
  7680.     @include_type bit = 0,
  7681.     @set_nulls    bit = 0,
  7682.     @op_type char(3) = 'ins', -- 'ins, 'upd', 'del'
  7683.     @is_new        bit = 0,
  7684.     @primary_key_bitmap varbinary(4000) = NULL
  7685. as
  7686.     declare @cmd          nvarchar(4000)
  7687.     declare @colname      sysname
  7688.     declare @ccoltype     sysname
  7689.     declare @src_cols     int
  7690.     declare @this_col     int
  7691.     declare @art_col      int
  7692.     declare @rc           int
  7693.     declare @column          nvarchar(4000)
  7694.  
  7695.     select @cmd = N''
  7696.  
  7697.     -- script cursor select variables
  7698.     select @src_cols = count(*) from syscolumns where id = @objid
  7699.     select @this_col = 1
  7700.     exec dbo.sp_MSpad_command @cmd output, @indent
  7701.  
  7702.     while @this_col <= @src_cols
  7703.     begin
  7704.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, null, 0, @colname output, @ccoltype output
  7705.             
  7706.     if @rc = 0 and EXISTS (select name from syscolumns where id=@objid and colid=@this_col and iscomputed<>1)
  7707.     begin
  7708.         if @prefix is null
  7709.         begin
  7710.             
  7711.             if (@set_nulls = 1)
  7712.             begin
  7713.                 -- Optimization:
  7714.                 -- Get null or actual column name
  7715.                 -- Note: the output is quoted.
  7716.                 exec dbo.sp_MSget_synctran_column 
  7717.                         @ts_col,
  7718.                         @op_type, -- 'ins, 'upd', 'del'
  7719.                         @is_new,
  7720.                         @primary_key_bitmap,
  7721.                         @colname,
  7722.                         @this_col,
  7723.                         @column output,
  7724.                         0,
  7725.                         @ccoltype
  7726.                 select @cmd = @cmd + @spacer + @column + isnull(@postfix, N'')
  7727.             end
  7728.             else
  7729.                 select @cmd = @cmd + @spacer + N'[' + @colname + isnull(@postfix, N'') + N']'
  7730.         end
  7731.         else
  7732.            select @cmd = @cmd + @spacer + isnull(@prefix, N'') + N'c' + RTRIM(convert(nvarchar(4), @this_col)) + isnull(@postfix, N'')
  7733.  
  7734.         if @include_type = 1
  7735.             begin
  7736.             declare @typestring nvarchar(100)
  7737.             exec dbo.sp_MSget_type @objid, @this_col, @colname output, @typestring OUTPUT
  7738.             select @cmd = @cmd +  N' ' + @typestring 
  7739.             end
  7740.  
  7741.         -- new vars of type timestamp and identity are declared as output params
  7742.         if (@bOutput_params = 1 and (@ccoltype = N'timestamp' or ColumnProperty(@objid, @colname, 'IsIdentity') = 1))
  7743.                or
  7744.                (@colname = @identity_col or @colname = @ts_col)
  7745.             begin
  7746.                 -- YWU: Do this to avoid output in cursor declaration statement.
  7747.                 -- The right thing seems to be set output only when bOutput_params is set
  7748.                 -- but it seems not the way this sp is called.
  7749.                 if @set_nulls = 0
  7750.                     select @cmd = @cmd + N' output'
  7751.             end
  7752.             
  7753.  
  7754.         select @spacer = N','
  7755.         end
  7756.         
  7757.         exec dbo.sp_MSflush_command @cmd output, 0, @indent
  7758.     select @this_col = @this_col + 1
  7759.     end
  7760.  
  7761.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  7762.     insert into #proctext(procedure_text) values(N'
  7763. ') 
  7764.  
  7765. go
  7766.  
  7767. raiserror('Creating procedure sp_MSscript_trigger_assignment', 0,1)
  7768. go
  7769.  
  7770. create procedure sp_MSscript_trigger_assignment
  7771.     @objid int,
  7772.     @postfix char(4) = null,
  7773.     @indent int = 0,
  7774.     @ts_col sysname,
  7775.     @op_type char(3), -- 'ins, 'upd', 'del'
  7776.     @is_new    bit,
  7777.     @primary_key_bitmap varbinary(4000)
  7778. as
  7779.     declare @cmd          nvarchar(4000)
  7780.     declare @colname      sysname
  7781.     declare @spacer       nvarchar(1)
  7782.     declare @ccoltype     sysname
  7783.     declare @src_cols     int
  7784.     declare @this_col     int
  7785.     declare @art_col      int
  7786.     declare @rc           int
  7787.     declare @column          nvarchar(4000)
  7788.  
  7789.     -- script cursor select variables
  7790.     select @src_cols = count(*) from syscolumns where id = @objid
  7791.     select @spacer = N' '
  7792.     select @this_col = 1
  7793.     exec dbo.sp_MSpad_command @cmd output, @indent
  7794.  
  7795.     while @this_col <= @src_cols
  7796.     begin
  7797.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, null, 0, @colname output, @ccoltype output
  7798.         if @rc = 0  and EXISTS (select name from syscolumns where id=@objid and @this_col=colid and iscomputed<>1)
  7799.         begin
  7800.  
  7801.             -- Optimization:
  7802.             -- Get null or actual column name
  7803.             -- Note: the output is quoted.
  7804.             exec dbo.sp_MSget_synctran_column 
  7805.                     @ts_col,
  7806.                     @op_type, -- 'ins, 'upd', 'del'
  7807.                     @is_new,
  7808.                     @primary_key_bitmap,
  7809.                     @colname,
  7810.                     @this_col,
  7811.                     @column output
  7812.  
  7813.             select @cmd = @cmd + @spacer + N'@c' + 
  7814.                 convert(varchar(4), @this_col) + isnull(@postfix, N'') + 
  7815.                 N' = ' + @column  
  7816.                 
  7817.             select @spacer = N','
  7818.         end
  7819.         
  7820.         exec dbo.sp_MSflush_command @cmd output, 0, @indent
  7821.         select @this_col = @this_col + 1
  7822.     end
  7823.  
  7824.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  7825.     insert into #proctext(procedure_text) values(N'
  7826. ') 
  7827.  
  7828. go
  7829.  
  7830. raiserror('Creating procedure sp_MSscript_trigger_fetch_statement', 0,1)
  7831. go
  7832.  
  7833. create procedure sp_MSscript_trigger_fetch_statement
  7834.     @objid   int, 
  7835.     @op_type char(3) = 'ins',
  7836.     @indent   int = 0
  7837. as
  7838.     declare @cmd          nvarchar(4000)
  7839.  
  7840.     exec dbo.sp_MSpad_command @cmd output, @indent
  7841.   
  7842.     -- script fetch statements
  7843.     if @op_type in ('ins', 'upd')
  7844.     begin
  7845.         exec dbo.sp_MSpad_command @cmd output, @indent
  7846.         select @cmd = @cmd + (N'fetch next from rpl_ins_cursor into 
  7847. ')
  7848.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  7849.         exec dbo.sp_MSscript_trigger_variables @objid, '@', null, @indent, ' '
  7850.     end
  7851.  
  7852.     if @op_type in ('ins')
  7853.     begin
  7854.         exec dbo.sp_MSpad_command @cmd output, @indent
  7855.         select @cmd = @cmd + (N'fetch next from rpl_ins2_cursor into 
  7856. ')
  7857.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  7858.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ' '
  7859.     end
  7860.  
  7861.     if @op_type in ('upd', 'del')
  7862.     begin
  7863.         exec dbo.sp_MSpad_command @cmd output, @indent
  7864.         select @cmd = @cmd + (N'fetch next from rpl_del_cursor into 
  7865. ')
  7866.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  7867.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ' '
  7868.     end
  7869. go
  7870.  
  7871. raiserror('Creating procedure sp_MSscript_trigger_exec_rpc ', 0,1)
  7872. go
  7873. create procedure sp_MSscript_trigger_exec_rpc 
  7874.     @publisher   sysname,
  7875.     @publisherdb sysname,
  7876.     @procname   sysname,
  7877.     @proc_owner sysname,
  7878.     @objid       int, 
  7879.     @op_type     char(3) = 'ins', 
  7880.     @indent      int = 0,
  7881.     @identity_col sysname = null,
  7882.     @ts_col       sysname = null
  7883. as
  7884.     declare @cmd nvarchar(4000)
  7885.     declare @min_identity int
  7886.     declare @max_identity int
  7887.  
  7888.     insert into #proctext(procedure_text) values (N'    if @connect_string is null 
  7889.      begin 
  7890. ')
  7891.     
  7892.     select @cmd = N'        exec @retcode = ' + 
  7893.         quotename(@publisher)    + N'.' + 
  7894.     quotename(@publisherdb) + N'.' + 
  7895.     quotename(@proc_owner)    + N'.' + 
  7896.     quotename(@procname) 
  7897.     -- 1st two variables are subscriber server name and database name for cycle detection
  7898.     select @cmd = @cmd + ' ' + 
  7899.     quotename(@@SERVERNAME) + N', ' + 
  7900.     quotename(db_name()) + N', 
  7901. '
  7902.     exec dbo.sp_MSflush_command @cmd, 1, @indent
  7903.     select @min_identity = @@identity
  7904.  
  7905.     if @op_type in ('ins', 'upd')
  7906.         exec dbo.sp_MSscript_trigger_variables @objid, '@', N'', @indent, N'', 0,  @identity_col, @ts_col
  7907.  
  7908.     if @op_type = 'upd'
  7909.     begin
  7910.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ',', 0, null, null
  7911.         insert into #proctext(procedure_text) values (N', @bitmap')
  7912.     end
  7913.  
  7914.     else if @op_type = 'del'
  7915.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ' ', 0, null, null
  7916.  
  7917.     select @max_identity = @@identity
  7918.     
  7919.     -- Raise friendly error.
  7920.     insert into #proctext(procedure_text) values (N'        
  7921.          if @@error <>0 or @retcode <> 0 
  7922.          begin 
  7923.              exec sp_MSreplraiserror 21054
  7924.              goto FAILURE 
  7925.          end
  7926. ')
  7927.     
  7928.     -- End if @connect is null
  7929.     insert into #proctext(procedure_text) values (N'    end 
  7930.      else 
  7931.      begin 
  7932. ')
  7933.     
  7934.     select @cmd = '        select @rpc_proc = N''declare @retcode int 
  7935.          exec @retcode = '' + N'
  7936.     select @cmd = @cmd + quotename('OpenDataSource(''SQLOLEDB'',N' ,'''') 
  7937.     select @cmd = @cmd + '+ '''''''' + replace(@connect_string, '''''''', '''''''''''''''') + N'''''''' + '
  7938.     select @cmd = @cmd + 'N'').'' + N''' 
  7939.     select @cmd = @cmd + quotename(@publisherdb)    + '.'
  7940.     select @cmd = @cmd + quotename(@proc_owner)        + '.'
  7941.     select @cmd = @cmd + quotename(@procname)        + ''' + N'
  7942.     select @cmd = @cmd + quotename(quotename(@@SERVERNAME),'''')    + ' + '','' + N'
  7943.     select @cmd = @cmd + quotename(quotename(db_name()),'''')        + ' + '','' + ''
  7944. '
  7945.     exec dbo.sp_MSflush_command @cmd, 1, @indent
  7946.  
  7947.      -- Get parameters
  7948.     if @op_type in ('ins', 'upd')
  7949.         exec dbo.sp_MSscript_trigger_variables @objid, '@', N'', @indent, N'', 0,  @identity_col, @ts_col
  7950.  
  7951.     if @op_type = 'upd'
  7952.     begin
  7953.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', @indent, ',', 0, null, null
  7954.         insert into #proctext(procedure_text) values (N', @bitmap')
  7955.     end
  7956.  
  7957.     else if @op_type = 'del'
  7958.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', @indent, ' ', 0, null, null
  7959.  
  7960.     -- Must raise error right before exiting the dynamic exec so that it will be picked up.
  7961.     insert into #proctext(procedure_text) values 
  7962.         (N'            '' + '' if @@error <>0 or @retcode <> 0 exec sp_MSreplraiserror 21054''
  7963.  
  7964. ')
  7965.  
  7966.     -- Get parameter datatypes
  7967.     insert into #proctext(procedure_text) values
  7968.         (N'        select @rpc_types = ''')
  7969.     if @op_type in ('ins', 'upd')
  7970.         exec dbo.sp_MSscript_trigger_variables @objid, '@', N'' , @indent, N'', 0,  @identity_col, @ts_col, 1
  7971.     if @op_type = 'upd'
  7972.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', @indent, ',', 0, null, null, 1
  7973.     else if @op_type = 'del'
  7974.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', @indent, ' ', 0, null, null, 1
  7975.     insert into #proctext(procedure_text) values (N'            ''')
  7976.  
  7977.     if @op_type = 'upd'
  7978.     begin
  7979.         insert into #proctext(procedure_text) values 
  7980.             (N' select @rpc_types = @rpc_types + '', @bitmap varbinary(4000)'' ')
  7981.     end
  7982.  
  7983.     -- make rpc call
  7984.     insert into #proctext(procedure_text) values 
  7985.         (N'        
  7986.          exec @retcode = dbo.sp_executesql @rpc_proc,  @rpc_types, 
  7987. ')
  7988.  
  7989.     -- Get parameters again
  7990.     insert into #proctext(procedure_text) select procedure_text from #proctext
  7991.     where c1 > @min_identity and c1 <= @max_identity
  7992.     order by c1 asc
  7993.  
  7994.     insert into #proctext(procedure_text) values (N'        
  7995.          if @@error <>0 goto FAILURE
  7996. ')
  7997.  
  7998.     -- end else
  7999.     insert into #proctext(procedure_text) values (N'     end
  8000. ')
  8001. go
  8002.  
  8003. raiserror('Creating procedure sp_MSscript_trigger_update_checks', 0,1)
  8004. go
  8005.  
  8006. create procedure sp_MSscript_trigger_update_checks
  8007.     @objid int,
  8008.     @identity_col sysname,
  8009.     @ts_col       sysname,
  8010.     @op_type varchar(3) = 'ins', -- 'pk', 'ins', 'upd'
  8011.     @indent int = 0
  8012. as
  8013.     declare @cmd          nvarchar(4000)
  8014.     declare @colname      sysname
  8015.     declare @ccoltype     sysname
  8016.     declare @src_cols     int
  8017.     declare @this_col     int
  8018.     declare @rc           int
  8019.     declare @qualname     nvarchar(512)
  8020.     declare @indid        int
  8021.     declare @key          sysname
  8022.     declare @indkey       int
  8023.  
  8024.  
  8025.     if @op_type = 'pk'
  8026.     begin
  8027.         select @indkey = 1
  8028.         exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  8029.         exec @indid = dbo.sp_MStable_has_unique_index @objid
  8030.         if @indid > 0
  8031.           begin
  8032.             exec dbo.sp_MSpad_command @cmd output, @indent
  8033.             while @indkey < 16 and index_col(@qualname, @indid, @indkey) is not null
  8034.             begin
  8035.                 select @key = index_col(@qualname, @indid, @indkey)
  8036.                 select @cmd = N'if update(' + @key + N')
  8037. '
  8038.                 exec dbo.sp_MSflush_command @cmd output, 1, @indent
  8039.                 insert into #proctext(procedure_text) values(N'begin
  8040.      exec sp_MSreplraiserror 20517
  8041.      goto FAILURE
  8042.  end 
  8043.  
  8044. ')
  8045.                 select @indkey = @indkey + 1
  8046.             end
  8047.         end
  8048.     end
  8049.     else
  8050.     begin
  8051.         -- Image cols
  8052.         select @src_cols = count(*) from syscolumns where id = @objid
  8053.         select @this_col = 1
  8054.     exec dbo.sp_MSpad_command @cmd output, @indent
  8055.    
  8056.         while @this_col <= @src_cols
  8057.         begin
  8058.             exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, null, 1, @colname output, @ccoltype output
  8059.             if @rc = 0  and EXISTS (select name from syscolumns where id=@objid and @this_col=colid and iscomputed<>1)
  8060.             begin
  8061.                 if @ccoltype in ('text','ntext','image')
  8062.                 begin
  8063.                 if @op_type = 'ins'
  8064.                     begin
  8065.                         select @cmd = N'if update(' +  quotename(@colname) + ') 
  8066. '
  8067.                         exec dbo.sp_MSflush_command @cmd output, 1, 0
  8068.                         insert into #proctext(procedure_text) values(N'    exec sp_MSreplraiserror 20508
  8069. ')
  8070.                     end
  8071.                     else if @op_type = 'upd'
  8072.                     begin
  8073.                         select @cmd = N'if update(' +  quotename(@colname) + ') 
  8074.                         exec dbo.sp_MSflush_command @cmd output, 1, 0
  8075.                         insert into #proctext(procedure_text) values(N'begin
  8076.      exec sp_MSreplraiserror 20509
  8077.      goto FAILURE 
  8078.  end
  8079.  
  8080. ')
  8081.                     end
  8082.                 end
  8083.             end
  8084.             select @this_col = @this_col + 1
  8085.         end
  8086.     end
  8087.  
  8088.     -- identity col
  8089.     if @op_type = 'upd' and @identity_col is not null
  8090.     begin
  8091.         select @cmd = N'if update(' +  quotename(@identity_col) + N') 
  8092. '
  8093.         exec dbo.sp_MSflush_command @cmd, 1
  8094.         insert into #proctext(procedure_text) values(N'begin
  8095.      exec sp_MSreplraiserror 20510
  8096.      goto FAILURE
  8097.  end
  8098.  
  8099. ')
  8100.     end
  8101.  
  8102.     -- timestamp col
  8103.     if @op_type = 'upd' and @ts_col is not null
  8104.     begin
  8105.         select @cmd = N'if update(' +  quotename(@ts_col) + N') 
  8106. '
  8107.         exec dbo.sp_MSflush_command @cmd, 1
  8108.         insert into #proctext(procedure_text) values(N'begin
  8109.      exec sp_MSreplraiserror 20511
  8110.      goto FAILURE
  8111.  end
  8112.  
  8113. ')
  8114.     end
  8115.  
  8116. go    
  8117.  
  8118. raiserror('Creating procedure sp_MSscript_trigger_updates', 0,1)
  8119. go
  8120. create procedure sp_MSscript_trigger_updates
  8121.     @identity_col sysname,
  8122.     @ts_col       sysname,
  8123.     @op_type      char(3) = 'ins', -- 'ins', 'del'
  8124.     @objid        int,
  8125.     @indent       int = 0
  8126. as
  8127.     declare @cmd nvarchar(4000)
  8128.     declare @col sysname
  8129.     declare @qualname nvarchar(512)
  8130.  
  8131.     if @op_type = 'upd'
  8132.     begin
  8133.         -- Script out pk var assigment that used in sp_MSscript_where_clause
  8134.         exec dbo.sp_MSscript_pkvar_assignment @objid, NULL, 1, @identity_col, @ts_col
  8135.  
  8136.         insert into #proctext(procedure_text) values(N'
  8137.     ')
  8138.     end
  8139.  
  8140.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  8141.  
  8142.     if @ts_col is not null
  8143.     begin
  8144.         insert into #proctext(procedure_text) values(N' 
  8145. ')
  8146.         exec dbo.sp_MSpad_command @cmd output, @indent
  8147.         exec dbo.sp_MSget_col_position @objid, null, @ts_col, @col output
  8148.         select @cmd = @cmd + N'update ' + @qualname + N' set ' + @ts_col + N' = @' + @col
  8149.         exec dbo.sp_MSflush_command @cmd, 1
  8150.  
  8151.         exec dbo.sp_MSscript_where_clause @objid, null, 'trg pk', null, @indent, @op_type
  8152.     end
  8153.  
  8154.    if @op_type = 'ins' and @identity_col is not null
  8155.     begin
  8156.         insert into #proctext(procedure_text) values(N' 
  8157. ')
  8158.         exec dbo.sp_MSpad_command @cmd output, @indent
  8159.         exec dbo.sp_MSget_col_position @objid, null, @identity_col, @col output
  8160.         select @cmd = @cmd + N'update ' + @qualname + N' set ' + @identity_col + N' = @' + @col
  8161.         exec dbo.sp_MSflush_command @cmd, 1
  8162.  
  8163.         exec dbo.sp_MSscript_where_clause @objid, null, 'trg pk', null, @indent, @op_type
  8164.     end
  8165. go
  8166.  
  8167. raiserror('Creating procedure sp_MSscript_singlerow_trigger', 0,1)
  8168. go
  8169. create procedure sp_MSscript_singlerow_trigger
  8170.     @objid        int,
  8171.     @publisher    sysname,
  8172.     @publisher_db sysname,
  8173.     @procname     sysname,
  8174.     @proc_owner      sysname,
  8175.     @identity_col  sysname,
  8176.     @ts_col        sysname,
  8177.     @op_type char(3) = 'ins', -- 'ins, 'upd', 'del'
  8178.     @primary_key_bitmap varbinary(4000) = NULL
  8179. as    
  8180.     declare @colname      sysname
  8181.     declare @spacer       nvarchar(1)
  8182.     declare @ccoltype     sysname
  8183.     declare @src_cols     int
  8184.     declare @this_col     int
  8185.     declare @rc           int
  8186.     
  8187.     select @src_cols = count(*) from syscolumns where id = @objid
  8188.  
  8189.     if @op_type in ('ins', 'upd')
  8190.         exec dbo.sp_MSscript_trigger_update_checks @objid, @identity_col, @ts_col, @op_type, 0
  8191.  
  8192.     insert into #proctext(procedure_text) values(N'if @rc = 1
  8193.  begin
  8194. ')
  8195.     if @op_type in ('ins', 'upd')
  8196.         begin
  8197.             insert into #proctext(procedure_text) values(N'    select')
  8198.         exec dbo.sp_MSscript_trigger_assignment @objid, null, 4, @ts_col, @op_type, 1, @primary_key_bitmap
  8199.             insert into #proctext(procedure_text) values(N'    from inserted
  8200.  
  8201. ')
  8202.         end
  8203.  
  8204.         if @op_type in ('ins')
  8205.         begin
  8206.             insert into #proctext(procedure_text) values(N'    select')
  8207.             exec dbo.sp_MSscript_trigger_assignment @objid, '_old', 4, @ts_col, @op_type, 0, @primary_key_bitmap
  8208.             insert into #proctext(procedure_text) values(N'    from inserted
  8209.  
  8210. ')
  8211.         end
  8212.         else if @op_type in ('upd', 'del')
  8213.         begin
  8214.             insert into #proctext(procedure_text) values(N'    select')
  8215.             exec dbo.sp_MSscript_trigger_assignment @objid, '_old', 4, @ts_col, @op_type, 0, @primary_key_bitmap
  8216.             insert into #proctext(procedure_text) values(N'    from deleted
  8217.  
  8218. ')
  8219.         end
  8220.   
  8221.         exec dbo.sp_MSscript_trigger_exec_rpc @publisher, @publisher_db, @procname, @proc_owner, @objid, @op_type, 12, @identity_col, @ts_col
  8222.         
  8223.         if @op_type in ('ins', 'upd')
  8224.         exec dbo.sp_MSscript_trigger_updates @identity_col, @ts_col, @op_type, @objid, 4
  8225.       
  8226.     insert into #proctext(procedure_text) values(N'end
  8227.  
  8228. ')
  8229. go
  8230.  
  8231. raiserror('Creating procedure sp_MSscript_multirow_trigger', 0,1)
  8232. go
  8233. create procedure sp_MSscript_multirow_trigger
  8234.     @objid        int,
  8235.     @publisher    sysname,
  8236.     @publisher_db sysname,
  8237.     @procname     sysname,
  8238.     @proc_owner      sysname,
  8239.     @identity_col  sysname,
  8240.     @ts_col        sysname,
  8241.     @op_type char(3) = 'ins', -- 'ins, 'upd', 'del'
  8242.     @primary_key_bitmap varbinary(4000) = NULL
  8243. as
  8244.  
  8245.     declare @cmd          nvarchar(4000)
  8246.  
  8247.     insert into #proctext(procedure_text) values(N'else
  8248.  begin
  8249. ')
  8250.         -- setup cursor over inserted table for ins & upd triggers
  8251.         if @op_type in ('ins', 'upd')
  8252.         begin
  8253.             insert into #proctext(procedure_text) values(N'    declare rpl_ins_cursor CURSOR LOCAL FAST_FORWARD FOR select 
  8254. ')
  8255.  
  8256.             exec dbo.sp_MSscript_trigger_variables @objid, null, null, 4, ' ',
  8257.                 0,@identity_col, @ts_col,0, 1, @op_type, 1, @primary_key_bitmap
  8258.         insert into #proctext(procedure_text) values(N'    from inserted for read only
  8259. ')
  8260.             insert into #proctext(procedure_text) values(N'    open rpl_ins_cursor
  8261.  
  8262. ')
  8263.         end
  8264.  
  8265.         if @op_type in ('ins')
  8266.         begin
  8267.             insert into #proctext(procedure_text) values(N'    declare rpl_ins2_cursor CURSOR LOCAL FAST_FORWARD FOR select 
  8268. ')
  8269.             exec dbo.sp_MSscript_trigger_variables @objid, null, null, 4, ' '
  8270.             insert into #proctext(procedure_text) values(N'    from inserted for read only
  8271. ')
  8272.             insert into #proctext(procedure_text) values(N'    open rpl_ins2_cursor
  8273.  
  8274. ')
  8275.         end
  8276.  
  8277.         -- setup cursor over deleted table for  upd & del triggers
  8278.         if @op_type in ('upd', 'del')
  8279.         begin
  8280.             insert into #proctext(procedure_text) values(N'    declare rpl_del_cursor CURSOR LOCAL FAST_FORWARD FOR select 
  8281. ')
  8282.             exec dbo.sp_MSscript_trigger_variables @objid, null, null, 4, ' ', 
  8283.                 0,@identity_col, @ts_col,0, 1,  @op_type, 0, @primary_key_bitmap
  8284.  
  8285.             insert into #proctext(procedure_text) values(N'    from deleted for read only
  8286. ')
  8287.             insert into #proctext(procedure_text) values(N'    open rpl_del_cursor
  8288.  
  8289. ')
  8290.         end
  8291.  
  8292.         -- script fetch statement
  8293.         exec dbo.sp_MSscript_trigger_fetch_statement @objid, @op_type, 4
  8294.  
  8295.         insert into #proctext(procedure_text) values(N' 
  8296. ')
  8297.         insert into #proctext(procedure_text) values(N'    while @@fetch_status <> -1
  8298.      begin
  8299. ')
  8300.         exec dbo.sp_MSscript_trigger_exec_rpc @publisher, @publisher_db, @procname, @proc_owner, @objid, @op_type, 16, @identity_col, @ts_col
  8301.         if @op_type in ('ins', 'upd')
  8302.             exec dbo.sp_MSscript_trigger_updates @identity_col, @ts_col, @op_type, @objid, 8
  8303.     exec dbo.sp_MSscript_trigger_fetch_statement @objid, @op_type, 8
  8304.         insert into #proctext(procedure_text) values(N'    
  8305.  end
  8306. ')
  8307.  
  8308.         if @op_type in ('ins', 'upd')
  8309.         begin
  8310.             insert into #proctext(procedure_text) values(N'    close rpl_ins_cursor
  8311.      deallocate rpl_ins_cursor
  8312. ')
  8313.         end
  8314.  
  8315.      if @op_type in ('upd', 'del')
  8316.         begin
  8317.             insert into #proctext(procedure_text) values(N'    close rpl_del_cursor
  8318.      deallocate rpl_del_cursor
  8319. ')
  8320.         end
  8321.  
  8322.     insert into #proctext(procedure_text) values(N'end
  8323. ')
  8324. go
  8325.  
  8326. go
  8327.  
  8328. raiserror('Creating procedure sp_MSscript_sync_ins_trig', 0,1)
  8329. go
  8330. create procedure sp_MSscript_sync_ins_trig
  8331.     @objid          int,
  8332.     @publisher    sysname,
  8333.     @publisher_db sysname,
  8334.     @trigname     sysname,
  8335.     @procname     sysname,
  8336.     @proc_owner   sysname,
  8337.     @identity_col sysname = NULL,
  8338.     @ts_col       sysname = NULL,
  8339.     @filter_clause nvarchar(4000)
  8340. as
  8341.     declare @colname      sysname
  8342.     declare @indid        int
  8343.     declare @cmd          nvarchar(4000)
  8344.     declare @ins_cmd      nvarchar(4000)
  8345.     declare @columns      binary(32)
  8346.     declare @outvars      nvarchar(4000)
  8347.     declare @rc           int
  8348.     declare @qualname     nvarchar(512)
  8349.  
  8350.     set nocount on
  8351.  
  8352.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  8353.  
  8354.     if @ts_col in ('null','NULL')
  8355.         select @ts_col = null
  8356.  
  8357.     if @identity_col in ('null','NULL')
  8358.         select @identity_col = null
  8359.  
  8360.         
  8361.     if @ts_col is null
  8362.     begin
  8363.         -- row compare method only supports updates
  8364.         select N'create trigger ' + QUOTENAME(@trigname) + N' on ' + @qualname + N' for insert  not for replication 
  8365. ' + 
  8366.             N'as 
  8367. ' + 
  8368.             N'    exec sp_MSreplraiserror 20518
  8369. ' + 
  8370.             N'    rollback transaction
  8371.     end
  8372.     else 
  8373.     begin
  8374.         -- Can't insert table with timestamp or identity col if no unique index
  8375.         exec @indid = dbo.sp_MStable_has_unique_index @objid    
  8376.         if (@ts_col is not null or @identity_col is not null) and @indid = 0
  8377.         begin
  8378.             select N'create trigger ' + QUOTENAME(@trigname) + N' on ' + @qualname + N' for insert  not for replication ' + 
  8379.                 N'as 
  8380. ' +
  8381.                 N'    exec sp_MSreplraiserror 20519
  8382. ' +
  8383.                 N'    rollback transaction
  8384.         end
  8385.         else 
  8386.         begin
  8387.             -- Create temp table
  8388.             create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  8389.  
  8390.             -- 1st preamble common to all synctran procs
  8391.             exec dbo.sp_MSscript_begintrig1 @trigname, @objid, @procname, @filter_clause, 'ins'
  8392.                         
  8393.             -- 2nd preamble common to all synctran procs
  8394.             exec dbo.sp_MSscript_begintrig2 @objid, 'ins'
  8395.  
  8396.             -- script single row handling
  8397.             exec @rc = dbo.sp_MSscript_singlerow_trigger @objid,@publisher, @publisher_db, @procname, @proc_owner, @identity_col, @ts_col, 'ins'
  8398.  
  8399.             -- script multi-row handling
  8400.             exec @rc = dbo.sp_MSscript_multirow_trigger @objid, @publisher, @publisher_db, @procname, @proc_owner, @identity_col, @ts_col, 'ins'
  8401.  
  8402.             -- script end of trigger
  8403.             exec dbo.sp_MSscript_endtrig 
  8404.  
  8405.             -- send fragments to client
  8406.             select procedure_text from #proctext order by c1 asc
  8407.         end
  8408.  
  8409.  
  8410.     end
  8411.  
  8412.  
  8413.  
  8414. go
  8415.  
  8416. raiserror('Creating procedure sp_MSscript_sync_upd_trig', 0,1)
  8417. go
  8418. create procedure sp_MSscript_sync_upd_trig
  8419.     @objid        int,
  8420.     @publisher    sysname,
  8421.     @publisher_db sysname,
  8422.     @trigname     sysname,
  8423.     @procname     sysname,
  8424.     @proc_owner   sysname,
  8425.     @identity_col sysname = NULL,
  8426.     @ts_col       sysname = NULL,
  8427.     @filter_clause nvarchar(4000),
  8428.     @primary_key_bitmap  varbinary(4000)
  8429. as
  8430.     declare @colname      sysname
  8431.     declare @indid        int
  8432.     declare @cmd          nvarchar(4000)
  8433.     declare @ins_cmd      nvarchar(4000)
  8434.     declare @columns      binary(32)
  8435.     declare @outvars      nvarchar(4000)
  8436.     declare @rc           int
  8437.     declare @qualname     nvarchar(512)
  8438.  
  8439.     set nocount on
  8440.  
  8441.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  8442.  
  8443.     if @ts_col in ('null','NULL')
  8444.         select @ts_col = null
  8445.  
  8446.     if @identity_col in ('null','NULL')
  8447.         select @identity_col = null
  8448.  
  8449.     exec @indid = dbo.sp_MStable_has_unique_index @objid    
  8450.     if @ts_col is not null and @indid = 0
  8451.     begin
  8452.         select N'create trigger ' + QUOTENAME(@trigname) + N' on ' + @qualname + N' for update  not for replication ' + 
  8453.             N'as 
  8454. ' + 
  8455.             N'    exec sp_MSreplraiserror 20520
  8456. ' + 
  8457.             N'    rollback transaction
  8458.     end
  8459.     else 
  8460.     begin
  8461.         -- Create temp table
  8462.         create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  8463.  
  8464.         -- 1st preamble common to all synctran procs
  8465.         exec dbo.sp_MSscript_begintrig1 @trigname, @objid, @procname, @filter_clause, 'upd'
  8466.                         
  8467.         -- trigger nesting checks
  8468.         insert into #proctext(procedure_text) values(N' 
  8469. ')
  8470.         insert into #proctext(procedure_text) values(N'declare @trigger_op char(10)
  8471. ')
  8472.         insert into #proctext(procedure_text) values(N'exec @retcode = dbo.sp_check_sync_trigger @@procid, @trigger_op OUTPUT 
  8473. ')
  8474.         insert into #proctext(procedure_text) values(N'if @retcode = 1 return 
  8475. ' )
  8476.  
  8477.         -- prevent updating of unique index when 'row compare' conflict detection, since it would trickle
  8478.         -- back as a del/insert, and fail
  8479.         if @ts_col is null
  8480.         begin
  8481.             insert into #proctext(procedure_text) values(N' 
  8482. ')
  8483.             exec dbo.sp_MSscript_trigger_update_checks @objid, null, null, 'pk', 0
  8484.         end
  8485.  
  8486.         -- 2nd preamble common to all synctran procs
  8487.         exec dbo.sp_MSscript_begintrig2 @objid, 'upd'
  8488.  
  8489.         -- script single row handling
  8490.         exec @rc = dbo.sp_MSscript_singlerow_trigger @objid,@publisher, @publisher_db, @procname, @proc_owner, @identity_col, @ts_col, 'upd', @primary_key_bitmap
  8491.  
  8492.         -- script multi-row handling
  8493.         exec @rc = dbo.sp_MSscript_multirow_trigger @objid,@publisher, @publisher_db, @procname, @proc_owner, @identity_col, @ts_col, 'upd', @primary_key_bitmap
  8494.         -- script end of trigger
  8495.         exec dbo.sp_MSscript_endtrig 
  8496.  
  8497.         -- send fragments to client
  8498.         select procedure_text from #proctext order by c1 asc
  8499.     end
  8500.  
  8501. go
  8502.  
  8503. raiserror('Creating procedure sp_MSscript_sync_del_trig', 0,1)
  8504. go
  8505. create procedure sp_MSscript_sync_del_trig
  8506.     @objid        int,
  8507.     @publisher    sysname,
  8508.     @publisher_db sysname,
  8509.     @trigname     sysname,
  8510.     @procname     sysname,
  8511.     @proc_owner      sysname,
  8512.     @identity_col sysname = NULL,
  8513.     @ts_col       sysname = NULL,
  8514.     @filter_clause nvarchar(4000),
  8515.     @primary_key_bitmap  varbinary(4000)
  8516. as
  8517.     declare @colname sysname
  8518.     declare @indid int
  8519.     declare @cmd          nvarchar(4000)
  8520.     declare @ins_cmd      nvarchar(4000)
  8521.     declare @columns      binary(32)
  8522.     declare @outvars      nvarchar(4000)
  8523.     declare @rc           int
  8524.     declare @qualname     nvarchar(512)
  8525.  
  8526.     set nocount on
  8527.  
  8528.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  8529.  
  8530.     if @ts_col in ('null','NULL')
  8531.         select @ts_col = null
  8532.  
  8533.     if @identity_col in ('null','NULL')
  8534.         select @identity_col = null
  8535.  
  8536.  
  8537.     if @ts_col is null
  8538.     begin
  8539.         -- row compare method only supports updates
  8540.         select N'create trigger ' + QUOTENAME(@trigname) + N' on ' + @qualname + N' for delete  not for replication ' + 
  8541.             N'as 
  8542. ' + 
  8543.             N'    exec sp_MSreplraiserror 20518
  8544. ' + 
  8545.             N'    rollback transaction
  8546. '  
  8547.     end
  8548.     else 
  8549.     begin
  8550.         exec @indid = dbo.sp_MStable_has_unique_index @objid    
  8551.         -- Create temp table
  8552.         create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  8553.  
  8554.         -- 1st preamble common to all synctran procs
  8555.         exec dbo.sp_MSscript_begintrig1 @trigname, @objid, @procname, @filter_clause, 'del'
  8556.                     
  8557.         -- 2nd preamble common to all synctran procs
  8558.         exec dbo.sp_MSscript_begintrig2 @objid, 'del'
  8559.  
  8560.         -- script single row handling
  8561.         exec @rc = dbo.sp_MSscript_singlerow_trigger @objid,@publisher, @publisher_db, @procname, @proc_owner, @identity_col, @ts_col, 'del', @primary_key_bitmap
  8562.  
  8563.         -- script multi-row handling
  8564.         exec @rc = dbo.sp_MSscript_multirow_trigger @objid,@publisher, @publisher_db, @procname, @proc_owner, @identity_col, @ts_col, 'del', @primary_key_bitmap
  8565.  
  8566.         -- script end of trigger
  8567.         exec dbo.sp_MSscript_endtrig 
  8568.  
  8569.         -- send fragments to client
  8570.         select procedure_text from #proctext order by c1 asc
  8571.     end
  8572.  
  8573. go
  8574.  
  8575. raiserror('Creating procedure sp_MSget_synctran_column', 0,1)
  8576. go
  8577. create procedure sp_MSget_synctran_column
  8578.     @ts_col sysname,
  8579.     @op_type char(3), -- 'ins, 'upd', 'del'
  8580.     @is_new    bit,
  8581.     @primary_key_bitmap varbinary(4000),
  8582.     @colname sysname,
  8583.     @this_col int, -- position in the table
  8584.     @column nvarchar(4000) output,
  8585.     @from_proc bit = 0,
  8586.     @coltype sysname = NULL,
  8587.     @type    varchar(10) = NULL,
  8588.     @art_col int = null -- position in the article partition.
  8589. as
  8590.     declare @bytestr      nvarchar(10)
  8591.     declare @bitstr       nvarchar(10)
  8592.     declare @typed_null      nvarchar(255)
  8593.  
  8594.     if @coltype is null
  8595.         select @typed_null = 'NULL'
  8596.     else
  8597.         select @typed_null = 'convert(' + @coltype + ', NULL)' 
  8598.  
  8599.     -- Optimization:
  8600.     -- If the column value is not needed, we set the corresponding
  8601.     -- param to null to reduce the network traffic. Here is the rule:
  8602.  
  8603.     -- For new values in update trigger,
  8604.     --    Set the param to column value or null depending on whether or
  8605.     --  or the column is updated.
  8606.     -- For old values 
  8607.     --    if ts col is replicated and the current column is not the ts col
  8608.     --    and the column is not in primary key, set the param to null
  8609.     -- For other cases
  8610.     --    set the param to column values.
  8611.  
  8612.     -- Called by proc
  8613.     if @type = 'pk_var'
  8614.     begin
  8615.         select @bytestr = convert( nvarchar, 1 + (@this_col-1) / 8 )
  8616.         select @bitstr =  convert( nvarchar, power(2, (@this_col-1) % 8 ) )
  8617.  
  8618.         select @column = N'case substring(@bitmap,' 
  8619.             + @bytestr + N',1) & ' + @bitstr +  
  8620.             N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @this_col ) + 
  8621.             N' else ' + N'@c'+ convert( nvarchar, @this_col )  + N'_old end'
  8622.     end
  8623.     else if (@from_proc = 1)
  8624.     begin
  8625.         select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  8626.         select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  8627.  
  8628.         select @column = N'case substring(@bitmap,' 
  8629.             + @bytestr + N',1) & ' + @bitstr +  
  8630.             N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @this_col ) + 
  8631.             N' else [' + @colname + N'] end'
  8632.     end
  8633.     -- Called in trigger,
  8634.     else if (@is_new = 1) and (@op_type = 'upd')
  8635.     begin
  8636.         -- @bitmap is set using columns_updated() at the beginning
  8637.         -- of the trigger.
  8638.         select @bytestr = convert( nvarchar, 1 + (@this_col-1) / 8 )
  8639.         select @bitstr =  convert( nvarchar, power(2, (@this_col-1) % 8 ) )
  8640.         
  8641.         select @column = N'case substring(@bitmap,' + @bytestr + N',1) & ' + @bitstr +  
  8642.             N' when ' + @bitstr + N' then [' + @colname + N'] ' + 
  8643.             N' else ' + @typed_null 
  8644.             +' end'
  8645.     end
  8646.     else if @is_new = 0 and @ts_col is not null and @colname <> @ts_col and
  8647.         (substring(@primary_key_bitmap, 1 + (@this_col-1) / 8 , 1) &
  8648.             power(2, (@this_col-1) % 8 )) = 0
  8649.         select @column =  @typed_null
  8650.     else 
  8651.         select @column = N'[' + @colname  + N'] '
  8652.     
  8653.     -- Add a new line
  8654.     select @column = @column + N'
  8655.     '
  8656. go
  8657.  
  8658. raiserror('Creating procedure sp_addsynctriggers', 0,1)
  8659. go
  8660.  
  8661. CREATE PROCEDURE sp_addsynctriggers 
  8662.     @sub_table       sysname,            -- table name 
  8663.     @sub_table_owner sysname,            -- table owner
  8664.     @publisher      sysname,            -- publishing server name
  8665.     @publisher_db   sysname,            -- publishing database name. If NULL then same as current db
  8666.     @publication    sysname,            -- publication name.
  8667.     @ins_proc       sysname,
  8668.     @upd_proc       sysname,
  8669.     @del_proc       sysname,
  8670.     @proc_owner        sysname,
  8671.     @identity_col   sysname = 'NULL', 
  8672.     @ts_col         sysname = 'NULL',
  8673.     @filter_clause  nvarchar(4000) = 'NULL',
  8674.     @primary_key_bitmap  varbinary(4000)
  8675. AS
  8676.     set nocount on
  8677.  
  8678.     declare @db                  sysname
  8679.     declare @trigname            sysname
  8680.     declare @ins_trig            sysname
  8681.     declare @upd_trig            sysname
  8682.     declare @del_trig            sysname
  8683.     declare @dbname              sysname
  8684.     declare @ccols               int
  8685.     declare @cnt                 int
  8686.     declare @retcode              int
  8687.     declare @cmd                 nvarchar(4000)
  8688.     declare @merge_pub_object_bit    int
  8689.     declare @synctran_bit        int
  8690.     declare @object_id            int
  8691.     declare @bitmap_str            varchar(8000)
  8692.     declare @constraint_name    sysname
  8693.     declare @quoted_name        nvarchar(500)
  8694.     declare @qualname            nvarchar(500)
  8695.  
  8696.     select @merge_pub_object_bit     = 128
  8697.     select @synctran_bit            = 256
  8698.  
  8699.     --  Security Check
  8700.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  8701.     IF @@ERROR <> 0 or @retcode <> 0
  8702.     RETURN(1)
  8703.  
  8704.     -- Dist Agent executes this sproc with 'implicit transasctions on'.
  8705.     -- We take care of our own transactions boundaries to get out of tran 
  8706.     while @@trancount > 0 commit tran
  8707.  
  8708.     -- check valid server and database setting
  8709.     -- 1. nested trigger have to be on
  8710.     if exists (select * from master..sysconfigures where config = 115 and value = 0)
  8711.     begin
  8712.         raiserror(21081, 16, 1)
  8713.         return (1)
  8714.     end
  8715.  
  8716.     -- 2. db option: recursive trigger have to be off
  8717.     if DATABASEPROPERTY(db_name(), N'IsRecursiveTriggersEnabled') <> 0
  8718.     begin
  8719.         raiserror(21082, 16, 1)
  8720.         return (1)
  8721.     end    
  8722.     
  8723.     -- 2. db compatibility level have to be 7.0
  8724.     if exists (select * from master..sysdatabases where dbid = db_id() and 
  8725.         cmptlevel < 70)
  8726.     begin
  8727.         raiserror(21083, 16, 1)
  8728.         return (1)
  8729.     end    
  8730.     
  8731.     if lower(@sub_table_owner) = N'null'
  8732.         select @qualname = QUOTENAME(@sub_table)        
  8733.     else
  8734.         select @qualname = QUOTENAME(@sub_table_owner) + N'.' + QUOTENAME(@sub_table)
  8735.  
  8736.     -- Verify that table exists 
  8737.     select @object_id = object_id (@qualname)
  8738.     if @object_id is null
  8739.     begin
  8740.         raiserror(20507, 16, 1, @qualname, 'sp_addsynctriggers')
  8741.         return (1)
  8742.     end
  8743.     
  8744.  
  8745.     -- Add default to timestamp and identity column
  8746.     select @constraint_name = 'MSrepl_synctran_ts_default_' + convert(nvarchar(10), @object_id)
  8747.     select @quoted_name = quotename(@ts_col)
  8748.     if @ts_col is not null and @ts_col not in ('null','NULL') and not exists
  8749.         (select * from sysobjects where name = @constraint_name)
  8750.     begin
  8751.         exec ('alter table ' + @qualname + 
  8752.             ' add constraint ' + @constraint_name + 
  8753.             ' default 0 for ' + @quoted_name )
  8754.         if @@ERROR<>0 return 1
  8755.     end
  8756.  
  8757.     select @constraint_name = 'MSrepl_synctran_identity_default_' + convert(nvarchar(10), @object_id)
  8758.     select @quoted_name = quotename(@identity_col)
  8759.     if @identity_col is not null and @identity_col not in ('null','NULL') and not exists
  8760.         (select * from sysobjects where name = @constraint_name)
  8761.     begin
  8762.         exec ('alter table ' + @qualname + 
  8763.             ' add constraint ' + @constraint_name + 
  8764.             ' default 0 for ' + @quoted_name )
  8765.         if @@ERROR<>0 return 1
  8766.     end
  8767.  
  8768.     -- If MSsubscription_properties table does not exists, create on.
  8769.     exec @retcode = dbo.sp_MScreate_sub_tables
  8770.     IF @@ERROR <> 0 or @retcode <> 0
  8771.         RETURN(1)
  8772.  
  8773.     -- If no entry in MSsubscription_properties for this publication, add one.
  8774.  
  8775.     IF NOT EXISTS (select * from MSsubscription_properties 
  8776.             where UPPER(publisher) = UPPER(@publisher)
  8777.                 and publisher_db =  @publisher_db
  8778.                 and publication = @publication) 
  8779.     BEGIN
  8780.         -- Use status rpc for local publisher, see bug 39385
  8781.         declare @security_mode int
  8782.         declare @login sysname
  8783.         if UPPER(@@servername) = UPPER(@publisher)
  8784.         begin
  8785.             select @security_mode = 2
  8786.         end
  8787.         else
  8788.         begin
  8789.             select @security_mode = 0
  8790.             select @login = 'sa'
  8791.         end
  8792.  
  8793.         exec @retcode = dbo.sp_link_publication
  8794.             @publisher = @publisher,
  8795.             @publisher_db = @publisher_db,
  8796.             @publication = @publication,
  8797.             @security_mode = @security_mode,
  8798.             @login = @login,
  8799.             @password = NULL
  8800.         IF @@ERROR <> 0 or @retcode <> 0
  8801.             RETURN(1)
  8802.     END
  8803.  
  8804.       
  8805.     if exists (select * from sysobjects where 
  8806.         replinfo & @merge_pub_object_bit <> 0 and
  8807.         id = @object_id)
  8808.     begin
  8809.         raiserror(21063, 16, 1, @qualname)
  8810.         return (1)
  8811.     end
  8812.  
  8813.     /*
  8814.     **    Create system table MSreplication_objects if it does not exist
  8815.     */
  8816.         IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  8817.             type = 'U' AND name = 'MSreplication_objects')
  8818.             BEGIN
  8819.                 CREATE TABLE dbo.MSreplication_objects
  8820.                 (
  8821.                 publisher sysname NULL,
  8822.                 publisher_db sysname NULL,
  8823.                    publication sysname NULL, 
  8824.                 object_name    sysname NOT NULL,
  8825.                 object_type    char(2) NOT NULL
  8826.                 )
  8827.                 IF @@ERROR <> 0
  8828.                     begin
  8829.                         rollback transaction 
  8830.                         return (1)
  8831.                     end
  8832.                 EXEC dbo.sp_MS_marksystemobject 'MSreplication_objects'
  8833.  
  8834.                 CREATE UNIQUE CLUSTERED INDEX ucMSreplication_objects ON dbo.MSreplication_objects(object_name)
  8835.  
  8836.                 IF @@ERROR <> 0
  8837.                     begin
  8838.                         rollback transaction 
  8839.                         return (1)
  8840.                     end
  8841.             END
  8842.  
  8843.  
  8844.     -- Drop all replication triggers on the source object
  8845.     -- We should drop all because we don't support updatable subscriptions to 
  8846.     -- multiple publications on same dest table.
  8847.     declare object_cursor CURSOR LOCAL FAST_FORWARD for 
  8848.         select o.object_name, so.id from MSreplication_objects o, sysobjects so where
  8849.             o.object_name = so.name and
  8850.             so.parent_obj = @object_id and
  8851.             o.object_type = 'T'
  8852.  
  8853.     declare @old_id int 
  8854.     declare @old_name sysname
  8855.  
  8856.     OPEN object_cursor
  8857.     FETCH object_cursor INTO @old_name, @old_id
  8858.      WHILE (@@fetch_status <> -1)
  8859.     BEGIN
  8860.         exec @retcode = dbo.sp_MSdrop_object 
  8861.             @object_id = @old_id
  8862.         if @retcode <> 0 or @@error <> 0
  8863.             goto UNDO
  8864.         delete from MSreplication_objects where object_name=@old_name
  8865.         FETCH object_cursor INTO @old_name, @old_id
  8866.     END
  8867.     CLOSE object_cursor
  8868.     DEALLOCATE object_cursor
  8869.  
  8870.     -- Generate trigger names
  8871.         select @trigname = RTRIM(SUBSTRING(@sub_table,1,110))
  8872.     select @ins_trig = N'trg_MSsync_ins_' + @trigname 
  8873.     select @upd_trig = N'trg_MSsync_upd_' + @trigname 
  8874.     select @del_trig = N'trg_MSsync_del_' + @trigname 
  8875.  
  8876.     -- check uniqueness of names and revert to ugly guid-based name if friendly name already exists
  8877.     if exists (select name from sysobjects where name in (@ins_trig, @upd_trig, @del_trig))
  8878.         begin
  8879.             declare @guid_name nvarchar(36)
  8880.             select @guid_name =  convert (nvarchar(36), newid())
  8881.         select @ins_trig = 'trg_MSsync_ins_' + @guid_name
  8882.         select @upd_trig = 'trg_MSsync_upd_' + @guid_name
  8883.         select @del_trig = 'trg_MSsync_del_' + @guid_name
  8884.         end
  8885.  
  8886.     exec @retcode = master..xp_varbintohexstr @primary_key_bitmap, @bitmap_str output
  8887.     if @retcode <> 0 or @@error <> 0
  8888.         return 1
  8889. /*
  8890.     exec ('if exists (select * from sysobjects where name = N''' + @ins_trig + N''' and xtype = N''TR'')
  8891.         drop trigger ' + @ins_trig)
  8892.     exec ('if exists (select * from sysobjects where name = N''' + @upd_trig + N''' and xtype = N''TR'')
  8893.         drop trigger ' + @upd_trig)
  8894.     exec ('if exists (select * from sysobjects where name = N''' + @del_trig + N''' and xtype = N''TR'')
  8895.         drop trigger ' + @del_trig)
  8896.  
  8897. */
  8898.     -- We are now going to create triggers, so start a transaction
  8899.     begin tran
  8900.  
  8901.         -- Call out to individual create trigger routines
  8902.         select @dbname = db_name()
  8903.         select @cmd = 'sp_MSscript_sync_ins_trig ' + 
  8904.             convert( nvarchar, @object_id )  + ', ' + 
  8905.             quotename(@publisher)     + ', ' + 
  8906.             quotename(@publisher_db)  + ', ' + 
  8907.             quotename(@ins_trig)      + ', ' + 
  8908.             quotename(@ins_proc)      + ', ' + 
  8909.             quotename(@proc_owner)      + ', ' + 
  8910.             quotename(@identity_col)  + ', ' + 
  8911.             quotename(@ts_col)        
  8912.         if @filter_clause in ('NULL', 'null')
  8913.             select @cmd = @cmd + ', null' 
  8914.         else 
  8915.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''
  8916.  
  8917.  
  8918.         exec master..xp_execresultset @cmd, @dbname
  8919.         IF @@ERROR <> 0
  8920.             goto UNDO
  8921.  
  8922.         select @cmd = 'sp_MSscript_sync_upd_trig ' + 
  8923.             convert( nvarchar, @object_id )  + ', ' + 
  8924.             quotename(@publisher)     + ', ' + 
  8925.             quotename(@publisher_db)  + ', ' + 
  8926.             quotename(@upd_trig)      + ', ' + 
  8927.             quotename(@upd_proc)      + ', ' + 
  8928.             quotename(@proc_owner)       + ', ' + 
  8929.             quotename(@identity_col)  + ', ' + 
  8930.             quotename(@ts_col)        
  8931.         if @filter_clause in ('NULL', 'null')
  8932.             select @cmd = @cmd + ', null' 
  8933.         else 
  8934.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''
  8935.                                     
  8936.         -- Update need primary key bitmap
  8937.          select @cmd = @cmd + ', ' + @bitmap_str
  8938.         
  8939.          exec master..xp_execresultset @cmd, @dbname
  8940.         IF @@ERROR <> 0
  8941.             goto UNDO
  8942.  
  8943.  
  8944.         select @cmd = 'sp_MSscript_sync_del_trig ' + 
  8945.             convert( nvarchar, @object_id )  + ', ' + 
  8946.             quotename(@publisher)     + ', ' + 
  8947.             quotename(@publisher_db)  + ', ' + 
  8948.             quotename(@del_trig)      + ', ' + 
  8949.             quotename(@del_proc)      + ', ' + 
  8950.             quotename(@proc_owner)       + ', ' + 
  8951.             quotename(@identity_col)  + ', ' + 
  8952.             quotename(@ts_col)        
  8953.         if @filter_clause in ('NULL', 'null')
  8954.             select @cmd = @cmd + ', null' 
  8955.         else 
  8956.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''            
  8957.  
  8958.         -- Delete need primary key bitmap
  8959.          select @cmd = @cmd + ', ' + @bitmap_str
  8960.         exec master..xp_execresultset @cmd, @dbname
  8961.         IF @@ERROR <> 0
  8962.             goto UNDO
  8963.  
  8964.         -- Drop old entries before insert. The triggers with those names
  8965.         -- are created as above.
  8966.         delete MSreplication_objects where object_name = @ins_trig
  8967.         IF @@ERROR <> 0
  8968.             goto UNDO
  8969.         delete MSreplication_objects where object_name = @upd_trig
  8970.         IF @@ERROR <> 0
  8971.             goto UNDO
  8972.         delete MSreplication_objects where object_name = @del_trig
  8973.         IF @@ERROR <> 0
  8974.             goto UNDO
  8975.  
  8976.         -- Mark procedures as system procs so they don't show up in the UI
  8977.         select @cmd = 'exec dbo.sp_MS_marksystemobject ' + quotename(@ins_trig)
  8978.         exec (@cmd)
  8979.         IF @@ERROR <> 0
  8980.             goto UNDO
  8981.  
  8982.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  8983.                     values(@publisher, @publisher_db, @publication, @ins_trig, 'T')
  8984.         IF @@ERROR <> 0
  8985.             goto UNDO
  8986.  
  8987.         select @cmd = 'exec dbo.sp_MS_marksystemobject ' + quotename(@upd_trig)
  8988.         exec (@cmd)
  8989.         IF @@ERROR <> 0
  8990.             goto UNDO
  8991.  
  8992.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  8993.                     values(@publisher, @publisher_db, @publication, @upd_trig, 'T')
  8994.         IF @@ERROR <> 0
  8995.             goto UNDO
  8996.  
  8997.         select @cmd = 'exec dbo.sp_MS_marksystemobject ' + quotename(@del_trig)
  8998.         exec (@cmd)
  8999.         IF @@ERROR <> 0
  9000.             goto UNDO
  9001.  
  9002.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  9003.                     values(@publisher, @publisher_db, @publication, @del_trig, 'T')
  9004.         IF @@ERROR <> 0
  9005.             goto UNDO
  9006.  
  9007.         -- Mark the table for warnings in BCP
  9008.         update sysobjects set replinfo = replinfo | @synctran_bit where
  9009.             id = @object_id
  9010.     -- commit tran
  9011.     commit tran
  9012.     return (0)
  9013. UNDO:
  9014.     if @@trancount <> 0
  9015.         rollback tran
  9016.     return(1)
  9017. go
  9018.  
  9019. raiserror('Creating procedure sp_helpreplicationdboption', 0,1)
  9020. go
  9021.  
  9022. CREATE PROCEDURE sp_helpreplicationdboption
  9023.         @dbname sysname = '%', @type sysname = 'replication allowed'
  9024.     AS
  9025.  
  9026.     SET NOCOUNT ON
  9027.  
  9028.     /*
  9029.     ** Declarations.
  9030.     */
  9031.  
  9032.     DECLARE @retcode int, @typebit int
  9033.     
  9034.     /* bit to distinguish distribution databases */
  9035.     DECLARE @distbit int
  9036.     SELECT @distbit = 16
  9037.  
  9038.     DECLARE @dbowner bit
  9039.     SELECT @dbowner = 0
  9040.     DECLARE @replication_db sysname
  9041.                 
  9042.     -- bug 24437 don't do security check.
  9043.  
  9044.     if (lower(@type) like 'publish%')
  9045.        select @typebit = 1
  9046.     else if (lower(@type) like 'subscribe%')
  9047.        select @typebit = 2
  9048.     else if (lower(@type) like 'merge publish%')
  9049.        select @typebit = 4
  9050.     else if (lower(@type) like 'merge subscribe%')
  9051.        select @typebit = 8
  9052.     else if (lower(@type) like 'replication allowed%')
  9053.         select @typebit = 0
  9054.     else        
  9055.         begin
  9056.             raiserror(14091,-1,-1)
  9057.             return 1
  9058.         end
  9059.  
  9060.     /*
  9061.     ** Parameter Check:  @dbname.
  9062.     ** Check to make sure that the database name conforms to the rules
  9063.     ** for identifiers.
  9064.     */
  9065.  
  9066.     IF @dbname <> '%'
  9067.        BEGIN
  9068.           EXECUTE @retcode = dbo.sp_validname @dbname
  9069.  
  9070.           IF @@ERROR <> 0 OR @retcode <> 0
  9071.             RETURN (1)
  9072.        END
  9073.  
  9074.     /*
  9075.     ** Show databases with this option enabled.
  9076.     */
  9077.     CREATE TABLE #replicationdbs (name sysname NOT NULL, id int identity NOT NULL, transpublish bit not null, mergepublish bit not null, dbowner bit not null)
  9078.     if @typebit <> 0
  9079.         begin
  9080.  
  9081.             INSERT INTO #replicationdbs (name, transpublish, mergepublish, dbowner)
  9082.                 SELECT name, 
  9083.                 case when (category & 1) <> 0 then 1 else 0 end,
  9084.                 case when (category & 4) <> 0 then 1 else 0 end,
  9085.                 @dbowner
  9086.                 FROM master..sysdatabases
  9087.                    WHERE name LIKE @dbname
  9088.                     AND (category & @typebit) <> 0 and
  9089.                     (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0)
  9090.  
  9091.             DECLARE hCdboinfo CURSOR LOCAL FAST_FORWARD FOR
  9092.                 SELECT name FROM #replicationdbs
  9093.                 FOR READ ONLY
  9094.             OPEN hCdboinfo
  9095.             FETCH hCdboinfo INTO @replication_db
  9096.             WHILE (@@fetch_status <> -1)
  9097.             BEGIN
  9098.                 EXEC @retcode = sp_MSrepl_isdbowner @replication_db
  9099.                 IF (@retcode IS NOT NULL) AND (@retcode <> 0)
  9100.                 BEGIN
  9101.                     UPDATE #replicationdbs set dbowner = 1 where name = @replication_db
  9102.                 END
  9103.                 FETCH hCdboinfo INTO @replication_db
  9104.             END
  9105.             CLOSE hCdboinfo
  9106.             DEALLOCATE hCdboinfo
  9107.  
  9108.             SELECT * FROM #replicationdbs
  9109.         end            
  9110.     else
  9111.         begin
  9112.             DECLARE @db_category int
  9113.  
  9114.             /* Filter out distribution databases */
  9115.             DECLARE hC  CURSOR LOCAL FAST_FORWARD FOR 
  9116.                 SELECT name, category FROM master..sysdatabases WHERE name LIKE @dbname
  9117.                     AND (category & @distbit) = 0  and
  9118.                     (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0)
  9119.             FOR READ ONLY
  9120.             OPEN hC
  9121.             FETCH hC INTO @replication_db, @db_category
  9122.             WHILE (@@fetch_status <> -1)
  9123.                 BEGIN
  9124.                     if @replication_db <> 'master' AND @replication_db <> 'model'
  9125.                         AND @replication_db <> 'tempdb' AND @replication_db <> 'msdb'
  9126.                         AND @replication_db <> 'MSSQLWeb'
  9127.                     BEGIN
  9128.                         EXEC @retcode = sp_MSrepl_isdbowner @replication_db
  9129.                         IF (@retcode IS NOT NULL) AND (@retcode <> 0)
  9130.                         BEGIN
  9131.                             SELECT @dbowner = 1
  9132.                         END
  9133.                         ELSE
  9134.                         BEGIN
  9135.                             SELECT @dbowner = 0
  9136.                         END
  9137.                         INSERT INTO #replicationdbs (name, transpublish, mergepublish, dbowner) VALUES (@replication_db,
  9138.                             case when (@db_category & 1) <> 0 then 1 else 0 end,
  9139.                             case when (@db_category & 4) <> 0 then 1 else 0 end,
  9140.                             @dbowner)
  9141.                     END
  9142.                     FETCH hC INTO @replication_db, @db_category
  9143.                 END
  9144.  
  9145.             CLOSE hC
  9146.             DEALLOCATE hC
  9147.  
  9148.             SELECT * FROM #replicationdbs
  9149.         end
  9150.         DROP TABLE #replicationdbs
  9151. go
  9152.  
  9153. raiserror('Creating procedure sp_MScheck_agent_instance', 0,1)
  9154. GO
  9155. CREATE PROCEDURE sp_MScheck_agent_instance
  9156. @application_name sysname,
  9157. @agent_type int = NULL
  9158.  
  9159. as
  9160.     declare @count_pro int
  9161.     set nocount on
  9162.     select @count_pro = count(*) from master..sysprocesses where 
  9163.         program_name = @application_name
  9164.     if @agent_type = 3
  9165.     begin
  9166.         -- The distribution agent will before connecting to the publisher with unique 
  9167.         -- application name
  9168.         if @count_pro > 0
  9169.             raiserror (21036, 16, -1, 'distribution')
  9170.     end
  9171.     else if @agent_type = 4
  9172.     begin
  9173.         -- The merge agent will connect to the publisher with unique application name
  9174.         -- then call this procedure
  9175.         if @count_pro > 1 
  9176.             raiserror (21036, 16, -1, 'merge')
  9177.     end
  9178.     else if @agent_type = 1
  9179.     begin
  9180.         -- The snapshot agent will connect to the distributiondb with unique application name
  9181.         -- then call this procedure
  9182.         if @count_pro > 2 
  9183.             raiserror (21036, 16, -1, 'snapshot')
  9184.     end
  9185.     else if @agent_type = 2
  9186.     begin
  9187.         -- The logreader agent will connect to the distributiondb with unique application name
  9188.         -- then call this procedure
  9189.         if @count_pro > 1 
  9190.             raiserror (21036, 16, -1, 'logreader')
  9191.     end
  9192. go
  9193.  
  9194. raiserror('Creating procedure sp_MSCleanupForPullReinit', 0,1)
  9195. GO
  9196.  
  9197. CREATE PROCEDURE sp_MSCleanupForPullReinit (
  9198.     @publication         sysname,
  9199.     @publisher_db        sysname,
  9200.     @publisher            sysname = @@servername
  9201.     ) AS
  9202.     declare @pubid         uniqueidentifier
  9203.     declare @parentid     uniqueidentifier
  9204.     declare @artid         uniqueidentifier
  9205.     declare @retcode    smallint
  9206.  
  9207.     /*
  9208.     ** Security Check
  9209.     */
  9210.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  9211.     IF @@ERROR <> 0 or @retcode <> 0
  9212.         return (1)
  9213.  
  9214.     /* This only gets called after database is enable to subscribe, so sysmergepublications should exist */
  9215.     select @pubid = pubid, @parentid = parentid FROM sysmergepublications 
  9216.         WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisher_db
  9217.  
  9218.     /* Normal case - nothing to cleanup, just return */
  9219.     if @pubid is null
  9220.         return (1)    
  9221.  
  9222.     delete from MSmerge_genhistory where pubid = @pubid
  9223.     delete from sysmergesubsetfilters where pubid=@pubid
  9224.     delete from sysmergeschemachange where pubid = @pubid
  9225.     delete from MSmerge_contents where tablenick in (select nickname from sysmergearticles where pubid=@pubid)
  9226.     delete from MSmerge_tombstone where tablenick in (select nickname from sysmergearticles where pubid=@pubid)
  9227. GO
  9228. exec dbo.sp_MS_marksystemobject sp_MSCleanupForPullReinit
  9229. go
  9230.  
  9231. grant execute on dbo.sp_MSCleanupForPullReinit to public
  9232. go
  9233.  
  9234. raiserror('Creating procedure sp_MSpublicationcleanup', 0,1)
  9235. GO
  9236.  
  9237. CREATE PROCEDURE sp_MSpublicationcleanup (
  9238.     @publication         sysname,
  9239.     @publisher_db        sysname,
  9240.     @publisher            sysname = @@servername
  9241.     ) AS
  9242.     declare @pubid         uniqueidentifier
  9243.     declare @parentid     uniqueidentifier
  9244.     declare @artid         uniqueidentifier
  9245.     declare @retcode    smallint
  9246.  
  9247.     /*
  9248.     ** Security Check
  9249.     */
  9250.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  9251.     IF @@ERROR <> 0 or @retcode <> 0
  9252.         return (1)
  9253.  
  9254.     /* This only gets called after database is enable to subscribe, so sysmergepublications should exist */
  9255.     select @pubid = pubid, @parentid = parentid FROM sysmergepublications 
  9256.         WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisher_db
  9257.  
  9258.     /* Normal case - nothing to cleanup, just return */
  9259.     if @pubid is null
  9260.         return (1)
  9261.  
  9262.     /* Clean up the articles for this publication, and delete the row */
  9263.     select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  9264.     while @artid is not null
  9265.         begin
  9266.         if not exists (select * from sysmergearticles WHERE artid = @artid and pubid <> @pubid)
  9267.             begin
  9268.                 exec @retcode=sp_MSarticlecleanup @pubid, @artid
  9269.                 if @retcode<>0 or @@ERROR<>0 return (1)
  9270.             end
  9271.         delete from sysmergearticles where artid = @artid and pubid = @pubid
  9272.         set @artid = NULL
  9273.         select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  9274.         end
  9275.         
  9276.     /* Now clean up any traces in other system tables */
  9277.     
  9278.  
  9279.     delete from MSmerge_genhistory where pubid = @pubid
  9280.     delete from MSmerge_replinfo where repid in (select subid from sysmergesubscriptions where pubid = @pubid and status <> 2)
  9281.     delete from sysmergesubsetfilters where pubid=@pubid
  9282.     delete from sysmergesubscriptions where pubid = @pubid and status <> 2
  9283.     delete from sysmergepublications where pubid = @pubid
  9284.     delete from sysmergeschemachange where pubid = @pubid
  9285. GO
  9286. exec dbo.sp_MS_marksystemobject sp_MSpublicationcleanup
  9287. go
  9288.  
  9289. grant execute on dbo.sp_MSpublicationcleanup to public
  9290. go
  9291.  
  9292. raiserror('Creating procedure sp_MSarticlecleanup', 0,1)
  9293. GO
  9294.  
  9295. create procedure sp_MSarticlecleanup
  9296.     (@pubid uniqueidentifier, @artid uniqueidentifier)
  9297. as
  9298.     set nocount on
  9299.     declare @source_table     nvarchar(258)
  9300.     declare @conflict_table nvarchar(258)
  9301.     declare @ownername         sysname
  9302.     declare @objectname     sysname
  9303.     declare @tablenick        int
  9304.     declare @objid             int
  9305.     declare @sync_objid     int
  9306.     declare @view_type        int
  9307.     declare @tsview            nvarchar(50)
  9308.     declare @guidstr        nvarchar(50)
  9309.     declare @csview            nvarchar(50)
  9310.     declare @viewname        nvarchar(258)
  9311.     declare @retcode        smallint
  9312.     declare @qualified_name    nvarchar(258)
  9313.     declare @bi_tablename    sysname
  9314.     declare    @bi_viewname    sysname
  9315.     declare @bi_procname    sysname
  9316.     
  9317.     -- to be called after article is set up in a subscriber
  9318.  
  9319.     /*
  9320.     ** Security Check
  9321.     */
  9322.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  9323.     IF @@ERROR <> 0 or @retcode <> 0
  9324.         return (1)
  9325.  
  9326.     select @objid = max(objid) from sysmergearticles where artid = @artid
  9327.  
  9328.     -- get owner name, and table name
  9329.     select @objectname = name, @ownername = user_name(uid)
  9330.         from sysobjects    where id = @objid
  9331.  
  9332.     -- construct the qualified table name
  9333.     select @source_table = @ownername + '.' + @objectname
  9334.  
  9335.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  9336.     if @retcode<>0 or @@ERROR<>0 return (1)
  9337.     
  9338.     -- get the insert, update and conflict proc names from sysmergearticles
  9339.     select     @sync_objid = sync_objid, 
  9340.             @view_type = view_type, 
  9341.             @tablenick = nickname,
  9342.             @bi_tablename = object_name(before_image_objid),
  9343.             @bi_viewname = object_name(before_view_objid),
  9344.             @conflict_table = conflict_table 
  9345.         from sysmergearticles where
  9346.             pubid = @pubid and artid = @artid
  9347.  
  9348.     /*
  9349.     ** We are not owner_qualifed this conflict table because it is created by snapshot agent
  9350.     */
  9351.     select @qualified_name = QUOTENAME(@conflict_table)
  9352.  
  9353.     /* Drop the conflict table */
  9354.     if (@conflict_table IS NOT NULL) and exists (select * from sysobjects where
  9355.             name = @conflict_table and type = 'U')
  9356.         begin
  9357.             exec ('drop table ' + @qualified_name)
  9358.             if @@ERROR<>0 return (1)
  9359.         end
  9360.  
  9361.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@conflict_table)
  9362.  
  9363.     /* If there is a before image table, drop it and its cleanup proc */
  9364.     if (@bi_tablename is not null)
  9365.         begin
  9366.         set @bi_procname = @bi_tablename + '_clean'
  9367.  
  9368.         if exists (select * from sysobjects where
  9369.             name = @bi_procname and type = 'P')
  9370.             begin
  9371.             exec ('drop proc ' + @bi_procname)
  9372.             if @@ERROR<>0 return (1)
  9373.             end
  9374.         exec ('drop table ' + @bi_tablename)
  9375.         if @@ERROR<>0 return (1)
  9376.         end
  9377.     /* If there is a before image view, drop it */
  9378.     if (@bi_viewname is not null)
  9379.         begin
  9380.         exec ('drop view ' + @bi_viewname)
  9381.         if @@ERROR<>0 return (1)
  9382.         end
  9383.  
  9384.     /* Drop the article procs */
  9385.     exec @retcode=sp_MSdroparticleprocs @pubid, @artid
  9386.     if @@ERROR<>0 or @retcode<>0 return (1)
  9387.  
  9388.     /* Drop the article triggers */
  9389.     exec @retcode=sp_MSdroparticletriggers @source_table
  9390.     if @@ERROR<>0 or @retcode<>0 return (1)
  9391.  
  9392.     exec @retcode=sp_MSunmarkreplinfo @objectname, @ownername
  9393.     if @@ERROR<>0 or @retcode<>0 return (1)
  9394.  
  9395.     /* If the article's has a temporary ( view type = 2) or a permanent view (view_type = 1 ) drop the sync object */
  9396.     if (@view_type = 1 OR @view_type = 2)
  9397.         begin
  9398.             select @viewname = sysobjects.name from sysobjects where 
  9399.                 ObjectProperty (sysobjects.id, 'IsView') = 1 
  9400.                 and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  9401.                 and sysobjects.id = @sync_objid
  9402.             if @viewname IS NOT NULL
  9403.                 begin
  9404.                     select @ownername = user_name(uid) from sysobjects where name=@viewname
  9405.                     set @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@viewname)
  9406.                     exec ('drop view ' + @viewname)
  9407.                     if @@ERROR<>0 return (1)
  9408.                 end
  9409.         end
  9410.  
  9411.     /*
  9412.     ** Drop the views created for MSmerge_contents and MSmerge_tombstone before dropping these two tables
  9413.     */
  9414.     set @csview = 'ctsv_' + @guidstr
  9415.     set @tsview = 'tsvw_' + @guidstr
  9416.     if EXISTS (select * from sysobjects where name=@csview and type='V')
  9417.     BEGIN
  9418.         select @ownername = user_name(uid) from sysobjects where  name=@csview
  9419.         select @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@csview)
  9420.         exec ('drop view ' + @viewname)
  9421.             if @@ERROR<>0 return (1)
  9422.     END
  9423.         
  9424.     if EXISTS (select * from sysobjects where name=@tsview and type='V')
  9425.     BEGIN
  9426.         select @ownername = user_name(uid) from sysobjects where  name=@tsview
  9427.         select @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@tsview)
  9428.         exec ('drop view ' + @viewname)
  9429.             if @@ERROR<>0 return (1)
  9430.     END
  9431.  
  9432.     /* Delete from contents, tombstone, delete conflicts */
  9433.     delete from MSmerge_contents where tablenick = @tablenick
  9434.     delete from MSmerge_tombstone where tablenick = @tablenick
  9435.     delete from MSmerge_delete_conflicts where tablenick = @tablenick
  9436. GO
  9437.  
  9438. exec dbo.sp_MS_marksystemobject sp_MSarticlecleanup
  9439. go
  9440.  
  9441. grant execute on dbo.sp_MSarticlecleanup to public
  9442. go
  9443.  
  9444. raiserror('Creating procedure sp_MSdroparticleprocs', 0,1)
  9445. GO
  9446.  
  9447. create procedure sp_MSdroparticleprocs
  9448.     (@pubid uniqueidentifier, @artid uniqueidentifier)
  9449. as
  9450.     set nocount on
  9451.     declare @ins_procname     sysname
  9452.     declare @upd_procname     sysname
  9453.     declare @conf_procname     sysname
  9454.     declare @sel_procname    sysname
  9455.     declare @tmp_procname    nvarchar(260)
  9456.     declare @view_sel_proc     sysname
  9457.     declare @owner            sysname
  9458.  
  9459.     declare @objid            int
  9460.     
  9461.     -- get the insert, update and conflict proc names from sysmergearticles
  9462.     select @ins_procname = insert_proc,    
  9463.             @upd_procname = update_proc, 
  9464.             @sel_procname = select_proc,
  9465.             @conf_procname = ins_conflict_proc,
  9466.             @view_sel_proc = view_sel_proc,
  9467.             @objid = objid
  9468.         from sysmergearticles where
  9469.             pubid = @pubid and artid = @artid
  9470.  
  9471.     if (@ins_procname IS NOT NULL) and exists (select * from sysobjects where
  9472.             name = @ins_procname and type = 'P')
  9473.         begin
  9474.             select @owner = user_name(uid) from sysobjects where name=@ins_procname
  9475.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@ins_procname)
  9476.             exec ('drop proc ' + @tmp_procname)
  9477.             if @@ERROR<>0 return (1)
  9478.             update sysmergearticles set insert_proc = NULL where pubid=@pubid and artid=@artid
  9479.         end
  9480.     if (@upd_procname IS NOT NULL) and exists (select * from sysobjects where
  9481.             name = @upd_procname and type = 'P')
  9482.         begin
  9483.             select @owner = user_name(uid) from sysobjects where name=@upd_procname
  9484.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@upd_procname)
  9485.             exec ('drop proc ' + @tmp_procname)
  9486.             if @@ERROR<>0 return (1)
  9487.             update sysmergearticles set update_proc = NULL where pubid=@pubid and artid=@artid
  9488.  
  9489.         end
  9490.     if (@sel_procname IS NOT NULL) and exists (select * from sysobjects where
  9491.             name = @sel_procname and type = 'P')
  9492.         begin
  9493.             select @owner = user_name(uid) from sysobjects where name=@sel_procname
  9494.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@sel_procname)
  9495.             exec ('drop proc ' + @tmp_procname)
  9496.             if @@ERROR<>0 return (1)
  9497.             update sysmergearticles set select_proc = NULL where pubid=@pubid and artid=@artid
  9498.         end
  9499.  
  9500.     if (@view_sel_proc IS NOT NULL) and exists (select * from sysobjects where
  9501.             name = @view_sel_proc and type = 'P')
  9502.         begin
  9503.             select @owner = user_name(uid) from sysobjects where name=@view_sel_proc
  9504.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@view_sel_proc)
  9505.             exec ('drop proc ' + @tmp_procname)
  9506.             if @@ERROR<>0 return (1)
  9507.             update sysmergearticles set view_sel_proc = NULL where pubid=@pubid and artid=@artid
  9508.         end
  9509.  
  9510.     if (@conf_procname IS NOT NULL) and    not exists (select * from sysmergearticles where
  9511.             artid=@artid and pubid<>@pubid) and exists (select * from sysobjects where
  9512.             name = @conf_procname and type = 'P')
  9513.         begin
  9514.             select @owner = user_name(uid) from sysobjects where name=@conf_procname
  9515.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@conf_procname)
  9516.             exec ('drop proc ' + @tmp_procname)
  9517.             if @@ERROR<>0 return (1)
  9518.             update sysmergearticles set ins_conflict_proc = NULL where pubid=@pubid and artid=@artid
  9519.         end
  9520.     return 0        
  9521.  
  9522. GO
  9523.  
  9524. exec dbo.sp_MS_marksystemobject sp_MSdroparticleprocs
  9525. go
  9526.  
  9527. raiserror('Creating procedure sp_MSdroparticletriggers', 0,1)
  9528. GO
  9529.  
  9530. create procedure sp_MSdroparticletriggers
  9531.     (@source_table nvarchar(258))
  9532. as
  9533.     set nocount on
  9534.     declare @instrigger     sysname
  9535.     declare @updtrigger     sysname
  9536.     declare @deltrigger     sysname
  9537.     declare @retcode        int
  9538.     declare @owner            sysname
  9539.     declare @artid            uniqueidentifier
  9540.     declare @guidstr        nvarchar(32)
  9541.  
  9542.     -- PARSENAME VARS
  9543.     declare      @UnqualName      sysname  --rightmost name node
  9544.     declare      @QualName1       sysname  
  9545.     -- END PARSENAME VARS
  9546.  
  9547.     select @UnqualName = PARSENAME(@source_table, 1)
  9548.     select @QualName1 = PARSENAME(@source_table, 2)
  9549.     if @UnqualName IS NULL
  9550.          return 1
  9551.     if @QualName1 is not NULL
  9552.         select @owner = @QualName1
  9553.             else select @owner = 'dbo'
  9554.     
  9555.     select @artid = artid from sysmergearticles where objid = object_id(@source_table)
  9556.  
  9557.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  9558.     if @retcode<>0 or @@ERROR<>0 return (1)
  9559.  
  9560.     set @instrigger = @owner + '.ins_' + @guidstr
  9561.     set @updtrigger = @owner + '.upd_' + @guidstr
  9562.     set @deltrigger = @owner + '.del_' + @guidstr
  9563.     
  9564. /*    
  9565.     select @instrigger = sysobjects.name from sysobjects where 
  9566.         ObjectProperty (sysobjects.id, 'ExecIsInsertTrigger') = 1 
  9567.         and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  9568.         and parent_obj = OBJECT_ID(@source_table) 
  9569.  
  9570.     select @updtrigger = sysobjects.name from sysobjects where 
  9571.         ObjectProperty (sysobjects.id, 'ExecIsUpdateTrigger') = 1 
  9572.         and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  9573.         and parent_obj = OBJECT_ID(@source_table) 
  9574.  
  9575.     select @deltrigger = sysobjects.name from sysobjects where 
  9576.         ObjectProperty (sysobjects.id, 'ExecIsDeleteTrigger') = 1 
  9577.         and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  9578.         and parent_obj = OBJECT_ID(@source_table) 
  9579. */
  9580.  
  9581.     if object_id(@instrigger) is not NULL
  9582.         begin
  9583.             exec ('drop trigger ' + @instrigger)
  9584.             if @@ERROR<>0 return (1)
  9585.         end
  9586.     if object_id(@updtrigger) is not NULL
  9587.         begin
  9588.             exec ('drop trigger ' + @updtrigger)
  9589.             if @@ERROR<>0 return (1)
  9590.         end
  9591.     if object_id(@deltrigger) IS NOT NULL
  9592.         begin
  9593.             exec ('drop trigger ' + @deltrigger)
  9594.             if @@ERROR<>0 return (1)
  9595.         end
  9596.  
  9597.     return 0
  9598. GO
  9599.  
  9600. exec dbo.sp_MS_marksystemobject sp_MSdroparticletriggers
  9601. go
  9602. grant execute on dbo.sp_MSdroparticletriggers to public
  9603.  
  9604. raiserror('Creating procedure sp_mergesubscription_cleanup', 0,1)
  9605. GO
  9606.  
  9607. CREATE PROCEDURE sp_mergesubscription_cleanup (
  9608.     @publisher        sysname,
  9609.     @publisher_db    sysname,
  9610.     @publication     sysname
  9611.     ) AS
  9612.     declare @pubid                 uniqueidentifier
  9613.     declare @parentid             uniqueidentifier
  9614.     declare @artid                 uniqueidentifier
  9615.     declare @retcode            smallint
  9616.     declare @subscription_type  int
  9617.  
  9618.     /*
  9619.     ** if there is nothing to cleanup, then just return.
  9620.     */
  9621.     if not exists (select * from sysobjects where name='sysmergesubscriptions')
  9622.         return (0)
  9623.         
  9624.     /* This only gets called after database is enable to subscribe, so sysmergepublications should exist */
  9625.     select @pubid = pubid, @parentid = parentid FROM sysmergepublications 
  9626.         WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  9627.  
  9628.     /* Normal case - nothing to cleanup, just return */
  9629.     if @pubid is null
  9630.         return (1)
  9631.  
  9632.     select @subscription_type = subscription_type from sysmergesubscriptions where pubid=@pubid and subid<>pubid
  9633.  
  9634.     /* This procedure is not intended to be used for cleanning-up pull/anonymous subscriptions */
  9635.     if @subscription_type > 0
  9636.         begin
  9637.             raiserror(20091, 16, -1)
  9638.             return (1)
  9639.         end
  9640.  
  9641.     /* Clean up the articles for this publication, and delete the row */
  9642.     select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  9643.     while @artid is not null
  9644.         begin
  9645.         if not exists (select * from sysmergearticles WHERE artid = @artid and pubid <> @pubid)
  9646.             begin
  9647.                 exec @retcode=sp_MSarticlecleanup @pubid, @artid
  9648.                 if @retcode<>0 or @@ERROR<>0 return (1)
  9649.             end
  9650.         delete from sysmergearticles where artid = @artid and pubid = @pubid
  9651.         set @artid = NULL
  9652.         select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  9653.         end
  9654.         
  9655.     /* Now clean up any traces in other system tables */
  9656.     
  9657.  
  9658.     delete from MSmerge_genhistory where pubid = @pubid
  9659.     delete from MSmerge_replinfo where repid in (select subid from sysmergesubscriptions where pubid = @pubid)
  9660.  
  9661.     delete from sysmergesubscriptions where pubid = @pubid
  9662.     delete from sysmergepublications where pubid = @pubid
  9663.     delete from sysmergeschemachange where pubid = @pubid
  9664. GO
  9665. exec dbo.sp_MS_marksystemobject sp_mergesubscription_cleanup
  9666. go
  9667. grant execute on dbo.sp_mergesubscription_cleanup to public
  9668.  
  9669. raiserror('Creating procedure sp_subscription_cleanup', 0,1)
  9670. GO
  9671. CREATE PROCEDURE sp_subscription_cleanup (
  9672.     @publisher        sysname,
  9673.     @publisher_db    sysname,
  9674.     @publication    sysname = NULL,
  9675.     @reserved        nvarchar(10) = NULL
  9676. )AS
  9677.  
  9678.     declare @object_name sysname
  9679.     declare @object_type char(2)
  9680.     declare @independent_agent bit
  9681.     declare @retcode int
  9682.     declare @synctran_bit int
  9683.     declare @parent_obj int
  9684.     declare @object_id int
  9685.  
  9686.     select @synctran_bit            = 256
  9687.  
  9688.     /*
  9689.     ** Security Check
  9690.     */
  9691.  
  9692.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  9693.     IF @@ERROR <> 0 or @retcode <> 0
  9694.         RETURN(1)
  9695.  
  9696.     if @publication = '' OR @publication is NULL
  9697.         select @independent_agent = 0
  9698.     else
  9699.         select @independent_agent = 1
  9700.  
  9701.     IF exists (select name from sysobjects where name = 'MSreplication_objects')
  9702.     BEGIN
  9703.         declare object_cursor CURSOR LOCAL FAST_FORWARD for 
  9704.             select DISTINCT object_name, object_type from MSreplication_objects o
  9705.                     where (UPPER(o.publisher) = UPPER(@publisher) and
  9706.                         o.publisher_db = @publisher_db and
  9707.                         o.publication = @publication) or
  9708.                         @reserved = 'drop_all'
  9709.  
  9710.         OPEN object_cursor
  9711.         FETCH object_cursor INTO @object_name, @object_type
  9712.          WHILE (@@fetch_status <> -1)
  9713.               BEGIN
  9714.                   IF @object_type = 'T' 
  9715.                   begin
  9716.                     select @parent_obj = NULL
  9717.                     select @parent_obj = parent_obj, @object_id = id from
  9718.                         sysobjects where name = @object_name 
  9719.                     if @parent_obj is not null
  9720.                     begin
  9721.                         -- Unmark synctran bit
  9722.                         update sysobjects set replinfo = replinfo & ~@synctran_bit where 
  9723.                             id = @parent_obj and
  9724.                             (replinfo & @synctran_bit) <> 0
  9725.                         IF @@ERROR <> 0 
  9726.                             GOTO UNDO
  9727.                         exec @retcode = dbo.sp_MSdrop_object 
  9728.                             @object_id = @object_id
  9729.                         if @retcode <> 0 or @@error <> 0
  9730.                             goto UNDO
  9731.                     end
  9732.                   end
  9733.                   delete from MSreplication_objects where object_name=@object_name
  9734.                   FETCH object_cursor INTO @object_name, @object_type
  9735.               END
  9736.         CLOSE object_cursor
  9737.         DEALLOCATE object_cursor
  9738.         
  9739.     if not exists (select * from MSreplication_objects) 
  9740.         drop table MSreplication_objects
  9741.         
  9742.     END
  9743.  
  9744.     IF exists (select name from sysobjects where name = 'MSreplication_subscriptions')
  9745.     BEGIN
  9746.     delete from MSreplication_subscriptions 
  9747.         where (UPPER(publisher) = UPPER(@publisher) AND
  9748.               publisher_db = @publisher_db AND
  9749.               (@independent_agent=0 or publication = @publication))
  9750.               or @reserved = 'drop_all'
  9751.  
  9752.     END
  9753.  
  9754.  
  9755.     IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties')
  9756.     BEGIN
  9757.         DELETE FROM MSsubscription_properties 
  9758.         WHERE (UPPER(publisher) = UPPER(@publisher)    AND
  9759.         publisher_db  = @publisher_db AND
  9760.         publication = @publication) 
  9761.         or @reserved = 'drop_all'
  9762.  
  9763.         IF @@ERROR <> 0 
  9764.             GOTO UNDO
  9765.  
  9766.         IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  9767.         BEGIN
  9768.             DROP TABLE MSsubscription_properties
  9769.             IF @@ERROR <> 0 
  9770.                 GOTO UNDO
  9771.         END
  9772.     END
  9773.     
  9774.     return (0)
  9775.             
  9776. UNDO:
  9777.     return(1)
  9778. GO
  9779. exec dbo.sp_MS_marksystemobject sp_subscription_cleanup 
  9780. go
  9781.  
  9782.  
  9783. raiserror('Creating procedure sp_get_distributor', 0,1)
  9784. go
  9785.  
  9786. -- Called by the UI to find out if the distributor is installed without doing RPC.
  9787. CREATE PROCEDURE sp_get_distributor 
  9788. AS
  9789.     SET NOCOUNT ON
  9790.  
  9791.     /*
  9792.     ** Declarations.
  9793.     */
  9794.     DECLARE @distributor sysname
  9795.     DECLARE @installed bit
  9796.     declare @distdb_installed bit
  9797.     declare @is_distpublisher bit
  9798.     declare @has_remote_distpublisher bit
  9799.      declare @distbit int
  9800.  
  9801.     SELECT @distbit = 16
  9802.        
  9803.     SELECT @distributor = datasource FROM master..sysservers
  9804.         WHERE srvstatus & 8 <> 0
  9805.  
  9806.     if @distributor is not null
  9807.         select @installed = 1
  9808.     else
  9809.         select @installed = 0
  9810.  
  9811.     if UPPER(@distributor) = UPPER(@@servername)
  9812.     begin
  9813.         if exists (select * from msdb.dbo.MSdistributiondbs) 
  9814.             select @distdb_installed = 1
  9815.         else
  9816.             select @distdb_installed = 0
  9817.  
  9818.         if exists (select * from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername))
  9819.             select @is_distpublisher = 1
  9820.         else
  9821.             select @is_distpublisher = 0
  9822.  
  9823.         if exists (select * from msdb..MSdistpublishers where UPPER(name) <> UPPER(@@servername))
  9824.             select @has_remote_distpublisher = 1
  9825.         else
  9826.             select @has_remote_distpublisher = 0
  9827.     end
  9828.     else
  9829.     begin
  9830.         select @distdb_installed = 0
  9831.         select @has_remote_distpublisher = 0    
  9832.         select @is_distpublisher = 0
  9833.     end
  9834.  
  9835.     select 'installed' = @installed, 'distribution server' = @distributor,
  9836.             'distribution db installed' = @distdb_installed,
  9837.             'is distribution publisher' = @is_distpublisher,
  9838.             'has remote distribution publisher' = @has_remote_distpublisher
  9839. GO
  9840.  
  9841. exec dbo.sp_MS_marksystemobject sp_get_distributor
  9842. go
  9843.  
  9844.  
  9845. -- Called by sp_addrolemember
  9846. raiserror('Creating procedure sp_MSrepl_addrolemember', 0,1)
  9847. go
  9848. CREATE PROCEDURE sp_MSrepl_addrolemember
  9849.     @rolename       sysname,
  9850.     @membername     sysname
  9851. AS
  9852.     -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
  9853.     set    nocount on
  9854.     
  9855.     return(0)
  9856.  
  9857. go        
  9858.  
  9859. exec dbo.sp_MS_marksystemobject sp_MSrepl_addrolemember
  9860. go
  9861.  
  9862. -- Called by sp_droprolemember
  9863. raiserror('Creating procedure sp_MSrepl_droprolemember', 0,1)
  9864. go
  9865. CREATE PROCEDURE sp_MSrepl_droprolemember
  9866.     @rolename       sysname,
  9867.     @membername     sysname
  9868. AS
  9869.     set    nocount on
  9870.     return(0)
  9871. go        
  9872.  
  9873. exec dbo.sp_MS_marksystemobject sp_MSrepl_droprolemember
  9874. go
  9875.  
  9876. raiserror('Creating procedure sp_table_validation', 0,1)
  9877. go
  9878.  
  9879. create procedure sp_table_validation
  9880. @table sysname,                    -- table name or sync object name
  9881. @expected_rowcount int = NULL OUTPUT,
  9882. @expected_checksum numeric = NULL OUTPUT,
  9883. @rowcount_only bit = 1,
  9884. @owner    sysname = NULL,
  9885. @full_or_fast tinyint = 2,        -- full (value 0) does COUNT(*) 
  9886.                                 -- fast (value 1) uses sysindexes.rows if table (not view); 
  9887.                                 -- conditional fast (VALUE 2) , first tries fast method, but
  9888.                                 -- reverts to full if fast method shows differences.
  9889. @shutdown_agent bit = 0,         -- If 1 will raise error 20578, which will signal replication agent to shutdown
  9890. @table_name sysname    = NULL        -- table name of sync object or the table name for output message
  9891.  
  9892. as
  9893.  
  9894. set nocount on
  9895.  
  9896. declare @num_rows int
  9897. -- RHS:  original proc by CC used INT.  
  9898. -- But INT will not be acceptable longer term - table may have more than 2bil rows
  9899. -- For now, leave it at INT and come back and improve this later.
  9900.  
  9901. declare @checksum numeric
  9902. declare @checksum_string varchar(100)
  9903. declare @expected_checksum_string varchar(100)
  9904. declare @width int
  9905. declare @qualified_table_name nvarchar(262)  -- two names plus []'s and a .
  9906. declare @temp_table_used bit
  9907. declare @retstatus int
  9908. declare @failed_fast tinyint
  9909. declare @min_indid int
  9910. declare @asked_for_exp_checksum tinyint
  9911. declare @asked_for_exp_rows tinyint
  9912.  
  9913. -- declare @debug tinyint   -- Temporary.   Take this out before beta 3 (or when TSQL debugger comes online)
  9914.  
  9915.  
  9916. SET @retstatus=0    -- initialize to SUCCESS
  9917. SET @failed_fast=0
  9918. -- SET @debug=0
  9919.  
  9920.  
  9921. if (@expected_checksum IS NULL AND @rowcount_only = 0 )  -- Wants an expected checksum value
  9922.     SET @asked_for_exp_checksum=1
  9923. ELSE
  9924.     SET @asked_for_exp_checksum=0
  9925.  
  9926.  
  9927. if (@expected_rowcount IS NULL)  -- Wants an expected checksum value
  9928.     SET @asked_for_exp_rows=1
  9929. ELSE
  9930.     SET @asked_for_exp_rows=0
  9931.  
  9932.  
  9933. -- RHS:  Should go back and do better parameter checking here
  9934. -- Some states do not make sense.  For example,  it does not make sense to ask for conditional
  9935. -- fast row count checking, yet not provide an expected value.  If this is done, provide a warning
  9936. -- message and use fast checking method.
  9937. if (@full_or_fast = 2 AND @expected_rowcount IS NULL)
  9938.     BEGIN
  9939.     -- Msg 20559,'Conditional Fast Rowcount method requested without specifying an expected count.  Fast method will be used.'
  9940.     raiserror (20559, 10, -1)
  9941.     SET @full_or_fast = 1
  9942.     END
  9943.  
  9944. -- Another state that doesn't make sense is to pass an expected checksum value, yet
  9945. -- ask for rowcount only validation
  9946. if (@expected_checksum IS NOT NULL AND @rowcount_only > 0)
  9947.     BEGIN
  9948.     -- Msg 20560,'An expected checksum value was passed, but checksums will not be compared because Rowcount only checking was requested.'
  9949.     raiserror (20560, 10, -1)
  9950.     SET @expected_checksum = NULL
  9951.     END
  9952.  
  9953.     
  9954. if @owner is null
  9955. begin
  9956.     if left(ltrim(rtrim(@table)), 1) <> '[' or right(ltrim(rtrim(@table)), 1) <> ']'
  9957.         set @qualified_table_name = '[' + @table + ']'
  9958.     else
  9959.         set @qualified_table_name = @table
  9960. end
  9961. else
  9962. begin
  9963.     if left(ltrim(rtrim(@table)), 1) <> '[' or right(ltrim(rtrim(@table)), 1) <> ']'
  9964.         set @qualified_table_name = '[' + @owner + '].[' + @table + ']'
  9965.     else
  9966.         set @qualified_table_name = '[' + @owner + '].' + @table
  9967. end
  9968.  
  9969.  
  9970. -- If the object is a table (not view) and fast checking (1) requested,
  9971. -- then get rowcount from sysindexes, rather than scanning
  9972. IF (SELECT @full_or_fast) > 0    -- IF Fast row checking asked for
  9973.     AND 
  9974.    (SELECT OBJECTPROPERTY(OBJECT_ID(@qualified_table_name),'IsTable')) > 0  -- Must be a table, not a view
  9975.  
  9976.     BEGIN
  9977.         -- Do the fast rowcount method
  9978.         -- Temporarily put a SHARE lock on table to ensure no simultaneous updates going on
  9979.         -- Minimizes chances of getting an out of date value from sysindexes.   True that
  9980.         -- it reduces concurrency, but if the fast method doesnt work the user will very likely
  9981.         -- go do the full method, which will be much more costly.   Better I think to take a little more cost here
  9982.         -- and hopefully get a good number.   The @foo variable is used so that its an
  9983.         -- assignment and doesn't make another result set get returned.
  9984.  
  9985.         -- DEBUG
  9986.         -- if @debug=1 PRINT "Querying for fast rowcount"
  9987.  
  9988.         BEGIN TRAN
  9989.         EXEC ('DECLARE @foo int SELECT @foo=1 FROM ' + @qualified_table_name + ' (TABLOCK HOLDLOCK) WHERE 1=2')
  9990.         SELECT @num_rows=rows,@min_indid=indid FROM sysindexes WHERE id=OBJECT_ID(@qualified_table_name)and indid < 2
  9991.         COMMIT TRAN
  9992.     END
  9993.  
  9994. ELSE 
  9995.     BEGIN
  9996.     -- if @debug=1 PRINT "setting variable to use full row count"
  9997.     SET @full_or_fast = 0   -- Full checking will be used, regardless of whether it was requested
  9998.     END
  9999.  
  10000. --    set the output name if not set
  10001.     if (@table_name IS NULL)
  10002.         SELECT @table_name = @table
  10003.  
  10004. -- If fast row checking was used, and request for rowcount check only, we're done.
  10005. if (@full_or_fast = 1  AND  @rowcount_only > 0) 
  10006.     BEGIN
  10007.     -- if @debug=1 PRINT "fast rowcount only requested & done - going to rowcount msg"
  10008.     GOTO ROWCOUNT_MSG
  10009.     END
  10010.  
  10011. -- If conditional fast row checking was used, and request for rowcount check only, 
  10012. -- we're also done IFF rows and expected rows match.
  10013. if (@full_or_fast = 2  AND  @rowcount_only > 0 
  10014.     AND @expected_rowcount IS NOT NULL AND @expected_rowcount=@num_rows)
  10015.     BEGIN
  10016.         -- Fast checking was actually used.
  10017.         -- if @debug=1 PRINT "conditional fast rowcount requested & passed - going to rowcount msg"
  10018.         SET @full_or_fast = 1
  10019.         GOTO ROWCOUNT_MSG
  10020.     END
  10021.  
  10022.  
  10023. -- If we're still here we are doing full row checking at a minimum, and will need the temp table
  10024. IF (SELECT ISNULL(OBJECT_ID('tempdb..#tab_validt1'),0)) = 0    -- Table Does Not exist
  10025.     CREATE TABLE #tab_validt1 (tmp_rows int NULL, tmp_checksum numeric NULL)
  10026. ELSE -- table already exists 
  10027.     TRUNCATE TABLE #tab_validt1
  10028.  
  10029. -- If we are only doing row checking, we'll do it here.  If we will do both row checking 
  10030. -- and checksum, then do them together so as to not scan table twice.
  10031. if @rowcount_only = 1
  10032.     BEGIN   -- Must do full count(*) checking but not checksums
  10033.     if @full_or_fast=2   
  10034.         -- if we are here with conditional check (2) requested, it is because
  10035.         -- a conditional was possible, but it failed.  We wiil later alert user of this.
  10036.         BEGIN 
  10037.         SET @full_or_fast=0
  10038.         SET @failed_fast=1
  10039.         END
  10040.     
  10041.     insert into #tab_validt1 (tmp_rows,tmp_checksum) 
  10042.         exec ('select count(*), NULL from ' +    @qualified_table_name + ' (TABLOCK HOLDLOCK)')
  10043.  
  10044.     -- Get row count value
  10045.     select  TOP 1 @num_rows = tmp_rows from #tab_validt1   -- Should only be one row
  10046.     -- if @debug=1 SELECT 'The TEMP TABLE HAS THIS MANY ROWS',count(*) from #tab_validt1 
  10047.     
  10048.     -- IF there were no rows from above, the table was empty so use ZERO.
  10049.     IF @num_rows IS NULL
  10050.         SELECT @num_rows=0
  10051.  
  10052.     -- Done with the temp table
  10053.     DROP TABLE #tab_validt1
  10054.     
  10055.     IF @expected_rowcount IS NULL
  10056.         BEGIN
  10057.         SET @expected_rowcount = @num_rows
  10058.         END
  10059.     GOTO ROWCOUNT_MSG
  10060.     END -- Done with full row count only
  10061.  
  10062. ELSE  -- Doing checksums in addition to ROWCOUNT
  10063.     BEGIN    -- DO checksum and rowcount in same pass thru the table
  10064.     insert into #tab_validt1 (tmp_rows,tmp_checksum)
  10065.         exec ('select count(*), sum (convert(numeric, getchecksum(NULL,1))) from ' +    @qualified_table_name + ' (TABLOCK HOLDLOCK)')
  10066.  
  10067.     -- Get the checksum & rowcount values
  10068.     select TOP 1 @checksum = tmp_checksum, @num_rows= tmp_rows from #tab_validt1
  10069.  
  10070.     -- IF there were no rows from above, the table was empty so use ZERO.
  10071.     IF @checksum IS NULL or @num_rows IS NULL
  10072.         SELECT @checksum=isnull(@checksum,0),@num_rows=isnull(@checksum,0)
  10073.  
  10074.     -- Done with the temp table
  10075.     DROP TABLE #tab_validt1
  10076.     
  10077.     IF @expected_rowcount IS NULL  -- Just getting value - no expected value yet.
  10078.         SET @expected_rowcount = @num_rows
  10079.     
  10080.     -- Validate checksum
  10081.     IF @expected_checksum is null        -- Just getting value - no expected value yet.
  10082.         set @expected_checksum = @checksum
  10083.     else
  10084.         -- Raise error if checksums OR rowcounts do not match
  10085.         if @checksum <> @expected_checksum OR @num_rows <> @expected_rowcount
  10086.             begin
  10087.             -- Checksum failed.
  10088.             set @checksum_string = convert(varchar(21), @checksum)
  10089.             set @expected_checksum_string = convert(varchar(21), @expected_checksum)
  10090.             -- Msg 20525: Table ''%s'' is out of synchronization. Rowcounts (actual: %d, expected %d).  Checksum difference (actual: %s, expected: %s).'
  10091.             raiserror (20525, 10, -1, @table, @num_rows, @expected_rowcount, @checksum_string, @expected_checksum_string)
  10092.             SET @retstatus=1
  10093.             END
  10094.         else
  10095.         BEGIN
  10096.         -- Row count and checksum validation passed.
  10097.         -- 
  10098.         if @asked_for_exp_checksum=0 -- Only give message if not generating the expected value
  10099.             raiserror (20527, 10, -1, @table,@num_rows)
  10100.         END
  10101.     -- Done with checksum and rowcount scan.
  10102.     END
  10103. -- We did checksum method, and so are done and skip over the rowcount only messages.
  10104. GOTO ALL_DONE
  10105.  
  10106. ROWCOUNT_MSG:
  10107. -- Raise error if rows counts do not match
  10108.     IF @expected_rowcount IS NULL  -- just return the found value
  10109.         SET @expected_rowcount=@num_rows
  10110.     ELSE
  10111.         IF @num_rows <> @expected_rowcount
  10112.         begin
  10113.        
  10114.             -- Msg 20524:  'Table ''%s'' may be out of synchronization. Row count difference encountered (actual: %d, expected: %d). Row count method %d used.  (0=Full  1=Fast)', NULL)
  10115.             raiserror (20524, 10, -1, @table_name, @num_rows, @expected_rowcount, @full_or_fast )
  10116.             SET @retstatus=1
  10117.         end
  10118.         ELSE    -- Row count validation passed. 
  10119.         begin
  10120.  
  10121.             if @asked_for_exp_rows=0 -- Only give message if not generating the expected value
  10122.                   -- Msg 20526:  'Table ''%s'' passed row count (%d) validation.  Row count method %d used. (0=Full  1=Fast)''
  10123.             raiserror (20526, 10, -1, @table_name, @num_rows, @full_or_fast)
  10124.             
  10125.             if @failed_fast=1
  10126.             BEGIN
  10127.             -- if we had to revert to FULL on a CONDITIONAL FAST, Make that known too.
  10128.             -- And Update usage to fix the problem
  10129.             -- Msg 20558: 'Table ''%s'' passed full row count validation after failing the fast check.  DBCC UPDATEUSAGE will be automatically initiated.'
  10130.             raiserror (20558, 10, -1, @table_name)
  10131.             DBCC UPDATEUSAGE (0,@qualified_table_name,@min_indid) WITH COUNT_ROWS, NO_INFOMSGS
  10132.             END
  10133.         end
  10134.  
  10135. ALL_DONE:
  10136.  
  10137. -- Give nice message if only generating the expected value:
  10138.  
  10139. -- Msg for rows and checksum:
  10140. if @asked_for_exp_checksum=1 and @asked_for_exp_rows=1 -- Only give message if generating the expected value
  10141.        BEGIN
  10142.        set @expected_checksum_string = convert(varchar(21), @expected_checksum)
  10143.        -- Msg 20579:'Generated expected rowcount value of %d and expected checksum value of %s for %s .'
  10144.        raiserror (20579, 10, -1, @expected_rowcount,@expected_checksum_string,@table_name)
  10145.        END
  10146.        
  10147. ELSE
  10148.     BEGIN
  10149.         if @asked_for_exp_checksum=0 and @asked_for_exp_rows=1
  10150.         -- Msg 20561:'Generated expected rowcount value of %d for %s .', 1033)
  10151.         raiserror (20561, 10, -1, @expected_rowcount, @table_name)
  10152.     END
  10153.         
  10154.  
  10155. -- Raise error that will shutdown replication agents
  10156. if @shutdown_agent = 1
  10157.     --Msg 20578: 'Shutdown replication agent request.'
  10158.     raiserror (20578, 10, -1)
  10159.     
  10160. return @retstatus
  10161. go
  10162.  
  10163. exec dbo.sp_MS_marksystemobject sp_table_validation
  10164. go
  10165.  
  10166. /* Create  sp_removedbreplication */
  10167. raiserror('Creating procedure sp_removedbreplication', 0,1)
  10168. GO
  10169.  
  10170. /* Permission to sysadmin */
  10171. CREATE PROCEDURE sp_removedbreplication (
  10172.       @dbname     sysname
  10173.     ) AS
  10174.  
  10175.     SET NOCOUNT ON
  10176.  
  10177.     /*
  10178.     ** Declarations.
  10179.     */
  10180.  
  10181.     DECLARE @retcode int
  10182.     DECLARE @proc nvarchar(255)
  10183.     DECLARE @optbit int
  10184.     DECLARE @restoreoverride int
  10185.     /*
  10186.     ** Initialization
  10187.     */
  10188.  
  10189.  
  10190.     /*
  10191.     ** Support override of replication remove on attach and restore
  10192.     */
  10193.  
  10194.     SELECT @restoreoverride = 0 -- assume normal remove behavior
  10195.     SELECT @proc = 'master.dbo.xp_regread '
  10196.     EXECUTE @retcode = @proc    'HKEY_LOCAL_MACHINE', 
  10197.                                 'SOFTWARE\Microsoft\MSSQLServer\Replication',
  10198.                                 'RestoreOverride',
  10199.                                 @param = @restoreoverride OUTPUT,
  10200.                                 @no_output = 'no_output'
  10201.  
  10202.     IF ( @@error = 0 ) and ( @retcode = 0 )
  10203.     BEGIN
  10204.         -- ReplRestoreOverride = 1 = user elects to take no cleanup on restore or attach
  10205.         IF ( ISNULL( @restoreoverride, 0 ) = 1 )
  10206.             RETURN(0)
  10207.     END
  10208.  
  10209.     /*
  10210.     ** Parameter check
  10211.     ** @dbname
  10212.     */
  10213.     IF NOT EXISTS (SELECT * FROM master.dbo.sysdatabases WHERE
  10214.         name = @dbname)
  10215.     BEGIN
  10216.         RAISERROR(15010, 16, -1, @dbname)
  10217.         RETURN(1)
  10218.     END
  10219.  
  10220.     
  10221.     SELECT @proc = quotename(@dbname) + '.dbo.sp_MSremovedbreplication'
  10222.     
  10223.     EXEC @retcode = @proc 
  10224.     IF @@ERROR <> 0 or @retcode <> 0
  10225.     BEGIN
  10226.         return (1)
  10227.     END
  10228.  
  10229.     -- Clear tran bit
  10230.     SELECT @optbit = 1
  10231.     IF EXISTS (SELECT * FROM master..sysdatabases
  10232.         WHERE name = @dbname
  10233.         AND (category & @optbit) <> 0)
  10234.     begin
  10235.         /*
  10236.         ** Toggle the category bit in master..sysdatabases
  10237.         */
  10238.         UPDATE master..sysdatabases SET category = category & ~@optbit
  10239.                 WHERE name = @dbname
  10240.         IF @@ERROR <> 0 
  10241.         BEGIN
  10242.             return (1)
  10243.         END
  10244.     end
  10245.  
  10246.     -- Clear merge bit
  10247.     SELECT @optbit = 4
  10248.     IF EXISTS (SELECT * FROM master..sysdatabases
  10249.         WHERE name = @dbname
  10250.         AND (category & @optbit) <> 0)
  10251.     begin
  10252.         /*
  10253.         ** Toggle the category bit in master..sysdatabases
  10254.         */
  10255.         UPDATE master..sysdatabases SET category = category & ~@optbit
  10256.                 WHERE name = @dbname
  10257.         IF @@ERROR <> 0 
  10258.         BEGIN
  10259.             return (1)
  10260.         END
  10261.     end
  10262.  
  10263.     /* 
  10264.      * Bug 47732 - cannot checkpoint in attach or restore
  10265.      * CHECKPOINT
  10266.      * IF @@ERROR <> 0 
  10267.      * BEGIN
  10268.      *     return (1)
  10269.      * END
  10270.     */
  10271. GO
  10272.  
  10273. exec dbo.sp_MS_marksystemobject sp_removedbreplication
  10274. go
  10275.  
  10276. raiserror('Creating procedure sp_removesrvreplication', 0,1)
  10277. GO
  10278.  
  10279. create procedure sp_removesrvreplication
  10280. as
  10281. begin
  10282. /* 
  10283.  * unmark replication bits for all servers, databases; used by setup in vupgrade 
  10284.  * assumes override is on; db in single user mode
  10285.  * no need to check rowcounts affected by updates, may not be any repl dbs
  10286.  * failure label avoids repetition of errs if not in single user mode
  10287. */
  10288.  
  10289.     set nocount on 
  10290.  
  10291.     -- server bits
  10292.     declare @srv_distbit int
  10293.     declare @srv_pubbit int
  10294.     declare @srv_subbit int
  10295.     declare @srv_dsnbit int
  10296.  
  10297.     select @srv_distbit = 8, @srv_pubbit = 16, @srv_subbit = 4, @srv_dsnbit = 32 -- dsn subscriber
  10298.  
  10299.     -- db bits
  10300.     declare @db_tranbit int
  10301.     declare @db_mergbit int
  10302.     declare @db_distbit int
  10303.  
  10304.     select @db_tranbit = 1, @db_mergbit = 4, @db_distbit = 16
  10305.  
  10306.     -- setup attach overrides removedb option
  10307.     declare @dbname sysname
  10308.  
  10309.     declare cur_db CURSOR LOCAL FAST_FORWARD for 
  10310.         select name from master..sysdatabases where name <> N'master'
  10311.         for read only
  10312.     open cur_db
  10313.     fetch cur_db into @dbname
  10314.     while ( @@fetch_status <> -1 )
  10315.     begin
  10316.         exec dbo.sp_removedbreplication @dbname
  10317.         -- clean up system tables
  10318.         exec ( @dbname + '.dbo.sp_MSdrop_pub_tables' )
  10319.         exec ( @dbname + '.dbo.sp_MSdrop_mergesystables' )
  10320.         fetch next from cur_db into @dbname
  10321.     end
  10322.     close cur_db
  10323.     deallocate cur_db
  10324.  
  10325.     -- unmark db bits
  10326.     -- select name, category from sysdatabases where category & @tranbit = @tranbit 
  10327.     update master..sysdatabases set category = category & ~@db_tranbit where category & @db_tranbit = @db_tranbit
  10328.     if @@ERROR <> 0
  10329.         goto fail
  10330.  
  10331.     update master..sysdatabases set category = category & ~@db_mergbit where category & @db_mergbit = @db_mergbit
  10332.     if @@ERROR <> 0
  10333.         goto fail
  10334.  
  10335.     -- clean up old dist db bit
  10336.     update master..sysdatabases set category = category & ~@db_distbit where category & @db_distbit = @db_distbit
  10337.     if @@ERROR <> 0
  10338.         goto fail
  10339.  
  10340.     -- unmark srv bits (srvstatus = @dsnbit no longer used by replication subscribers but by server )
  10341.     -- select name, srvstatus from sysservers where srvstatus & @srv_distbit = @srv_distbit
  10342.     update master..sysservers set srvstatus = srvstatus & ~@srv_subbit where srvstatus & @srv_subbit = @srv_subbit
  10343.     if @@ERROR <> 0
  10344.         goto fail
  10345.  
  10346.     update master..sysservers set srvstatus = srvstatus & ~@srv_pubbit where srvstatus & @srv_pubbit = @srv_pubbit
  10347.     if @@ERROR <> 0
  10348.         goto fail
  10349.  
  10350.     update master..sysservers set srvstatus = srvstatus & ~@srv_distbit where srvstatus & @srv_distbit = @srv_distbit
  10351.     if @@ERROR <> 0
  10352.         goto fail
  10353.  
  10354.     return (0)
  10355.  
  10356. fail:
  10357. -- ad hoc updates not allowed and not single user
  10358. return (1)
  10359.  
  10360. end
  10361. go
  10362.  
  10363. exec dbo.sp_MS_marksystemobject sp_removesrvreplication
  10364. go
  10365.  
  10366. raiserror('Creating procedure sp_MSremovedbreplication', 0,1)
  10367. GO
  10368.  
  10369. CREATE PROCEDURE sp_MSremovedbreplication
  10370.     AS
  10371.  
  10372.     SET NOCOUNT ON
  10373.  
  10374.     /*
  10375.     ** Declarations.
  10376.     */
  10377.  
  10378.     DECLARE @retcode int
  10379.  
  10380.     if exists (select * from sysobjects where name = 'sysarticles')
  10381.     -- clean up transactional 
  10382.     begin
  10383.         if not exists (select * from master..MSreplication_options
  10384.             where optname = 'transactional')
  10385.         begin
  10386.             RAISERROR(21027, 16, -1, 'transactional')
  10387.             return(1)
  10388.         end
  10389.     
  10390.         
  10391.         EXEC @retcode = dbo.sp_MSpublishdb @value = 'false',
  10392.             @ignore_distributor = 1
  10393.         IF @@ERROR <> 0 or @retcode <> 0
  10394.         BEGIN
  10395.             return (1)
  10396.         END
  10397.     end
  10398.  
  10399.     if exists (select * from sysobjects where name = 'sysmergearticles')
  10400.     -- clean up merge
  10401.     -- can not use sp_MSmergepublishdb or sp_dropmergepullsubscriptions
  10402.     -- since they depend on serverid and dbname
  10403.     begin
  10404.         declare @pubid uniqueidentifier
  10405.         declare @artid uniqueidentifier
  10406.         declare hC CURSOR LOCAL FAST_FORWARD FOR select DISTINCT pubid, artid FROM 
  10407.             sysmergearticles
  10408.         FOR READ ONLY       
  10409.  
  10410.         OPEN hC
  10411.         FETCH hC INTO @pubid, @artid
  10412.         WHILE (@@fetch_status <> -1)
  10413.         begin
  10414.  
  10415.             EXEC @retcode = dbo.sp_MSarticlecleanup
  10416.                 @pubid, @artid
  10417.             IF @@ERROR <> 0 or @retcode <> 0
  10418.             BEGIN
  10419.                 return (1)
  10420.             end
  10421.             FETCH hC INTO @pubid, @artid
  10422.         end
  10423.  
  10424.         execute @retcode = dbo.sp_MSdrop_mergesystables
  10425.         if @@ERROR <> 0 or @retcode <> 0
  10426.         begin
  10427.                 return (1)
  10428.         end
  10429.     end
  10430.  
  10431.  
  10432.     if exists (select * from sysobjects where name = 'MSreplication_subscriptions')
  10433.     -- clean up tran sub
  10434.     begin
  10435.         -- drop pull subscription
  10436.         EXEC @retcode = dbo.sp_droppullsubscription
  10437.             @publisher = N'all', 
  10438.             @publisher_db = N'all', 
  10439.             @publication = N'all'
  10440.         IF @@ERROR <> 0 or @retcode <> 0
  10441.         BEGIN
  10442.             return (1)
  10443.         END
  10444.  
  10445.         -- drop push subscription
  10446.         EXEC @retcode = dbo.sp_subscription_cleanup
  10447.             @publisher = N'all', 
  10448.             @publisher_db = N'all', 
  10449.             @publication = N'all',
  10450.             @reserved = 'drop_all'
  10451.         IF @@ERROR <> 0 or @retcode <> 0
  10452.         BEGIN
  10453.             return (1)
  10454.         END
  10455.     end
  10456.     
  10457. GO
  10458.  
  10459. exec dbo.sp_MS_marksystemobject sp_MSremovedbreplication
  10460. go
  10461.  
  10462. raiserror('Creating procedure sp_vupgrade_subscription_databases', 0,1)
  10463. GO
  10464. create procedure sp_vupgrade_subscription_databases
  10465. as
  10466.     declare @dbname sysname
  10467.  
  10468.     declare current_db CURSOR LOCAL FAST_FORWARD for 
  10469.         select quotename(name) from master..sysdatabases 
  10470.         for read only
  10471.  
  10472.     -- Note: dbname is quoted!
  10473.     open current_db
  10474.     fetch current_db into @dbname
  10475.     while ( @@fetch_status <> -1 )
  10476.     begin
  10477.         exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_mergetables')
  10478.         if @@ERROR<>0
  10479.             begin
  10480.                 close DC
  10481.                 deallocate DC
  10482.                 return (1)
  10483.             end
  10484.         exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_subscription_tables')
  10485.         if @@ERROR<>0
  10486.             begin
  10487.                 close DC
  10488.                 deallocate DC
  10489.                 return (1)
  10490.             end
  10491.         fetch next from current_db into @dbname
  10492.     end
  10493.     close current_db
  10494.     deallocate current_db
  10495. go
  10496. exec dbo.sp_MS_marksystemobject sp_vupgrade_subscription_databases
  10497. go
  10498.  
  10499.  
  10500.  
  10501. raiserror('Creating procedure sp_vupgrade_subscription_tables', 0,1)
  10502. GO
  10503. create procedure sp_vupgrade_subscription_tables
  10504. as
  10505.  
  10506. -- this raiserror makes sp_vupgrade_replication.out file easier to read
  10507. raiserror('sp_vupgrade_subscription_tables', 0,1)
  10508.  
  10509. DECLARE @table_name sysname
  10510.  
  10511. --    Create unique index on tables that did not have one previously. The index is not created
  10512. --    if duplicates rows exist in the table. 
  10513.  
  10514. --    MSreplication_subscriptions
  10515.     SELECT @table_name = N'MSreplication_subscriptions'
  10516.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSreplication_subscriptions' ) 
  10517.     BEGIN
  10518.         IF EXISTS ( SELECT publication, publisher_db, publisher, subscription_type 
  10519.             FROM MSreplication_subscriptions
  10520.             GROUP BY publication, publisher_db, publisher, subscription_type
  10521.             HAVING COUNT(*) > 1 )
  10522.             RAISERROR (21144, 10, 1, @table_name)
  10523.         ELSE
  10524.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSReplication_subscriptions' AND
  10525.                 id = OBJECT_ID('MSreplication_subscriptions') )
  10526.                 CREATE UNIQUE CLUSTERED INDEX uc1MSReplication_subscriptions ON
  10527.                 MSreplication_subscriptions(publication, publisher_db, publisher, subscription_type)
  10528.     END
  10529.  
  10530.     
  10531. --    MSsubscription_properties
  10532.     SELECT @table_name = N'MSsubscription_properties'
  10533.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSsubscription_properties' ) 
  10534.     BEGIN
  10535.         IF EXISTS ( SELECT publication, publisher_db, publisher
  10536.             FROM MSsubscription_properties
  10537.             GROUP BY publication, publisher_db, publisher
  10538.             HAVING COUNT(*) > 1 )
  10539.             RAISERROR (21144, 10, 2, @table_name)
  10540.         ELSE
  10541.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSsubscription_properties' AND
  10542.                 id = OBJECT_ID('MSsubscription_properties') )
  10543.                 CREATE UNIQUE CLUSTERED INDEX uc1MSsubscription_properties ON
  10544.                 MSsubscription_properties(publication, publisher_db, publisher)
  10545.     END
  10546.     
  10547. --    MSreplication_objects
  10548.     SELECT @table_name = N'MSreplication_objects'
  10549.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSreplication_objects' ) 
  10550.     BEGIN
  10551.         IF EXISTS ( SELECT object_name
  10552.             FROM MSreplication_objects
  10553.             GROUP BY object_name
  10554.             HAVING COUNT(*) > 1 )
  10555.             RAISERROR (21144, 10, 3, @table_name)
  10556.         ELSE    
  10557.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSreplication_objects' AND
  10558.                 id = OBJECT_ID('MSreplication_objects') )
  10559.                 CREATE UNIQUE CLUSTERED INDEX ucMSreplication_objects ON dbo.MSreplication_objects(object_name)
  10560.     END
  10561. go
  10562.  
  10563. exec dbo.sp_MS_marksystemobject sp_vupgrade_subscription_tables
  10564. go
  10565.  
  10566.  
  10567. raiserror('Creating procedure sp_vupgrade_mergetables', 0,1)
  10568. GO
  10569. create procedure sp_vupgrade_mergetables
  10570. as
  10571.  
  10572. -- this raiserror makes sp_vupgrade_replication.out file easier to read
  10573. raiserror('sp_vupgrade_mergetables', 0,1)
  10574.  
  10575.  
  10576. DECLARE @table_name sysname
  10577.  
  10578.  
  10579.     if (exists (select * from sysobjects where name = 'sysmergearticles'))
  10580.         begin
  10581.         -- Columns have been added to the sysmergearticles table
  10582.         if not exists (select * from syscolumns where id = object_id('sysmergearticles') and
  10583.                         name = 'gen_cur')
  10584.             begin
  10585.             alter table sysmergearticles add gen_cur int null
  10586.             if @@ERROR <> 0
  10587.                 return 1
  10588.             end
  10589.         if not exists (select * from syscolumns where id = object_id('sysmergearticles') and
  10590.                             name = 'before_image_objid')
  10591.             begin
  10592.             alter table sysmergearticles add before_image_objid    int    NULL
  10593.             if @@ERROR <> 0
  10594.                 return 1
  10595.             end
  10596.         if not exists (select * from syscolumns where id = object_id('sysmergearticles') and
  10597.                             name = 'before_view_objid')
  10598.             begin
  10599.             alter table sysmergearticles add before_view_objid    int    NULL
  10600.             if @@ERROR <> 0
  10601.                 return 1
  10602.             end
  10603.         end
  10604. --  MSmerge_contents    
  10605.     SELECT @table_name = N'MSmerge_contents'
  10606.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_contents' )
  10607.     BEGIN
  10608.         IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc3MSmerge_contents' AND
  10609.         id = OBJECT_ID('MSmerge_contents') )
  10610.                 create index nc3MSmerge_contents on MSmerge_contents(tablenick, partchangegen)
  10611.                 
  10612.         IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc4MSmerge_contents' AND
  10613.         id = OBJECT_ID('MSmerge_contents') )
  10614.                 create index nc4MSmerge_contents on MSmerge_contents(generation, partchangegen) 
  10615.     END
  10616.  
  10617. --    sysmergepublications
  10618.     SELECT @table_name = N'sysmergepublications'
  10619.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'sysmergepublications' )
  10620.     BEGIN 
  10621.         if not exists (select * from syscolumns where id = object_id('sysmergepublications')
  10622.             and name = 'keep_before_values')
  10623.         begin
  10624.         alter table sysmergepublications add keep_before_values int null
  10625.         if @@ERROR <> 0
  10626.             return 1
  10627.         end
  10628.  
  10629.         IF EXISTS ( SELECT pubid
  10630.             FROM sysmergepublications
  10631.             GROUP BY pubid
  10632.             HAVING COUNT(*) > 1 )
  10633.             RAISERROR (21144, 10, 4, @table_name)
  10634.         ELSE    
  10635.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc1sysmergepublications' AND
  10636.                 id = OBJECT_ID('sysmergepublications') )
  10637.             CREATE UNIQUE NONCLUSTERED INDEX nc1sysmergepublications
  10638.                 ON sysmergepublications(pubid)
  10639.     END
  10640.  
  10641. --    MSmerge_genhistory    
  10642.     SELECT @table_name = N'MSmerge_genhistory'
  10643.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_genhistory' )
  10644.     BEGIN
  10645.     -- Only create the index index if guidsrc values are unique. Before SP1 it was possible
  10646.     -- for this table to contain dup guidsrc. This happened when the genhistory table was empty to start 
  10647.     -- and we insert an initial row (for no article) and then try to insert a row for the first 
  10648.     -- article without generating a new guid.  
  10649.     
  10650.         IF EXISTS ( SELECT guidsrc, pubid 
  10651.             FROM MSmerge_genhistory 
  10652.             GROUP BY guidsrc, pubid 
  10653.             HAVING COUNT(*) > 1 )
  10654.             RAISERROR (21144, 10, 5, @table_name)
  10655.         ELSE            
  10656.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc3MSmerge_genhistory' AND
  10657.                 id = OBJECT_ID('MSmerge_genhistory') )
  10658.             CREATE UNIQUE NONCLUSTERED INDEX nc3MSmerge_genhistory ON MSmerge_genhistory(guidsrc, pubid)        
  10659.             
  10660.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc4MSmerge_genhistory' AND
  10661.                 id = OBJECT_ID('MSmerge_genhistory') )
  10662.             create  index nc4MSmerge_genhistory on MSmerge_genhistory(coldate) 
  10663.             
  10664.     END
  10665.     
  10666.  
  10667. --    MSmerge_delete_conflicts
  10668.     SELECT @table_name = N'MSmerge_delete_conflicts'
  10669.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_delete_conflicts' )
  10670.     BEGIN
  10671.         IF EXISTS ( SELECT tablenick, rowguid, origin_datasource
  10672.             FROM MSmerge_delete_conflicts
  10673.             GROUP BY tablenick, rowguid, origin_datasource
  10674.             HAVING COUNT(*) > 1 )
  10675.             RAISERROR (21144, 10, 6, @table_name)
  10676.         ELSE    
  10677.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc1MSmerge_delete_conflicts' AND
  10678.                 id = OBJECT_ID('MSmerge_delete_conflicts') )
  10679.                 CREATE UNIQUE NONCLUSTERED INDEX nc1MSmerge_delete_conflicts 
  10680.                     ON MSmerge_delete_conflicts(tablenick, rowguid, origin_datasource)
  10681.     END
  10682.     
  10683. --    sysmergeschemachange
  10684.     SELECT @table_name = N'sysmergeschemachange'
  10685.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'sysmergeschemachange' )
  10686.     BEGIN
  10687.         IF EXISTS ( SELECT schemaversion, pubid
  10688.             FROM sysmergeschemachange
  10689.             GROUP BY schemaversion, pubid
  10690.             HAVING COUNT(*) > 1 )
  10691.             RAISERROR (21144, 10, 7, @table_name)
  10692.         ELSE    
  10693.             BEGIN
  10694.                 IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'schemachangeversion' AND
  10695.                     id = OBJECT_ID('sysmergeschemachange') )            
  10696.                     DROP INDEX sysmergeschemachange.schemachangeversion
  10697.             
  10698.                 -- Recreate this index as unique clustered with one more field in index key.
  10699.                 CREATE UNIQUE CLUSTERED INDEX schemachangeversion ON sysmergeschemachange(schemaversion, pubid) 
  10700.             END
  10701.     END
  10702.     
  10703.  
  10704. --    sysmergesubsetfilters    
  10705.     SELECT @table_name = N'sysmergesubsetfilters'
  10706.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'sysmergesubsetfilters' )
  10707.     BEGIN
  10708.         IF EXISTS ( SELECT join_filterid
  10709.             FROM sysmergesubsetfilters
  10710.             GROUP BY join_filterid
  10711.             HAVING COUNT(*) > 1 )
  10712.             RAISERROR (21144, 10, 8, @table_name)
  10713.         ELSE    
  10714.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc1sysmergesubsetfilters' AND
  10715.                 id = OBJECT_ID('sysmergesubsetfilters') )
  10716.             CREATE UNIQUE NONCLUSTERED INDEX nc1sysmergesubsetfilters ON sysmergesubsetfilters(join_filterid, pubid)
  10717.     END    
  10718.  
  10719.  
  10720.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'sysmergepublications' )
  10721.     BEGIN 
  10722.     declare @artname sysname
  10723.     declare @pubname sysname
  10724.     declare @retcode int
  10725.  
  10726.     -- Must recreate the article procs for all articles that already have a select proc
  10727.     declare cur_articles CURSOR LOCAL FAST_FORWARD for 
  10728.         select a.name, p.name from sysmergearticles a, sysmergepublications p
  10729.             where a.select_proc is not null and a.pubid = p.pubid 
  10730.                 for read only
  10731.  
  10732.     open cur_articles 
  10733.     fetch cur_articles into @artname, @pubname
  10734.     while ( @@fetch_status <> -1 )
  10735.         begin
  10736.         exec @retcode = sp_MSsetartprocs @publication = @pubname,     @article = @artname, @force_flag = 1
  10737.         if @@ERROR <>0 OR @retcode <>0 return (1)
  10738.         fetch cur_articles into @artname, @pubname
  10739.         end
  10740.     close cur_articles 
  10741.     deallocate cur_articles 
  10742.     END
  10743. GO
  10744. exec dbo.sp_MS_marksystemobject sp_vupgrade_mergetables
  10745. go
  10746.  
  10747.  
  10748. raiserror('Creating procedure sp_vupgrade_replication', 0,1)
  10749. GO
  10750.  
  10751. create procedure sp_vupgrade_replication ( @login sysname = N'sa', @password sysname = N'', @ver_old int = 623, @security_mode bit = 0 )
  10752. as
  10753.  
  10754. -- this raiserror makes sp_vupgrade_replication.out file easier to read
  10755. raiserror('sp_vupgrade_replication', 0,1)
  10756.  
  10757. begin
  10758. /* 
  10759.  * Stub to handle possible need to modify or supplement replication metadata during setup 
  10760.  * initiated version upgrade from RTM to SP1. Any schema changes
  10761.  * to replication system tables may require modifications here to maintain upgrade path.
  10762.  * 
  10763.  * If server is a distributor, run new instdist.sql against all distribution dbs.
  10764.  * If version upgraded from is pre-Beta 3 OR @force_remove is true, do hard strip of replication.
  10765.  *
  10766.  * This proc gets called by setup at the end of an install over an existing version. 
  10767. */
  10768.  
  10769.     set nocount on 
  10770.  
  10771.     declare @dbname sysname
  10772.     declare @install_path nvarchar(255)
  10773.     declare @osql_cmd nvarchar(512)
  10774.     declare @osql_for_nt int
  10775.     declare @retcode int
  10776.     declare @platform_nt binary
  10777.     
  10778.     -- db bits
  10779.     declare @db_distbit int
  10780.  
  10781.     select @db_distbit = 16
  10782.  
  10783.     -- version check
  10784.     declare @ver_min             int
  10785.     
  10786.  
  10787.     select @platform_nt = 0x1
  10788.     select @ver_min= 623
  10789.     
  10790.  
  10791.     
  10792.         -- check for @ver_old < @ver_min and bailout if true. Should not even get 
  10793.         -- here since setup should have detected this earlier
  10794.     if ( @ver_old < @ver_min ) 
  10795.         return(1)
  10796.         
  10797.     else
  10798.     begin
  10799.  
  10800.         -- always need to run instdist.sql to update distribution databases on a distributor
  10801.         -- setup must restart in non-single user mode so we can shell out to run instdist.sql scripts
  10802.  
  10803.         if exists( select * from master..sysdatabases where category & @db_distbit = @db_distbit )
  10804.         begin
  10805.  
  10806.             -- get install_path
  10807.             exec @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  10808.                       'SOFTWARE\Microsoft\MSSQLServer\Setup',
  10809.                       'SQLPath',
  10810.                     @param = @install_path OUTPUT
  10811.  
  10812.             if ( @retcode <> 0 ) or ( @install_path is null ) or ( @install_path = N'' )
  10813.             begin
  10814.                 return(1)
  10815.             end
  10816.             
  10817.             -- Set the flag for platform
  10818.             if (( platform() & @platform_nt = @platform_nt ))
  10819.                 select @osql_for_nt = 1
  10820.             else
  10821.                 select @osql_for_nt = 0
  10822.  
  10823.             declare cur_distdb CURSOR LOCAL FAST_FORWARD for 
  10824.                 select name from master..sysdatabases 
  10825.                     where category & @db_distbit = @db_distbit
  10826.                 for read only
  10827.             
  10828.             open cur_distdb
  10829.             fetch cur_distdb into @dbname
  10830.             while ( @@fetch_status <> -1 )
  10831.             begin
  10832.  
  10833.                 /*
  10834.                  * Format osql cmd line appropriate for security mode and OS to run instdist.sql against
  10835.                  * each distribution database. Instdist.sql will recompile procs and will also do some
  10836.                  * schema and metadata upgrade of changed replication tables. Query timeout increased to
  10837.                  * make enough time for alter tables in instdist.sql run for upgrade to complete.
  10838.                 */
  10839.                 if (@osql_for_nt = 1)
  10840.                     select @osql_cmd = '" "'
  10841.                 else
  10842.                     select @osql_cmd = ' "'
  10843.                      
  10844.                 -- Cannot specify -S w/ -E for local execution, SID does not map (nofix)
  10845.                 if ( @security_mode = 1 and @osql_for_nt = 1 )
  10846.                     select @osql_cmd = @osql_cmd + @install_path + '\binn\osql" -E '
  10847.                 else
  10848.                     select @osql_cmd = @osql_cmd + @install_path + '\binn\osql" -U' + isnull(@login, N'sa') + ' -P' + isnull(@password, N'') + ' -S' + @@SERVERNAME
  10849.  
  10850.                 select @osql_cmd = @osql_cmd + ' -l30 -t30 '
  10851.                 select @osql_cmd = @osql_cmd + ' -b ' + ' -d' + @dbname
  10852.                 select @osql_cmd = @osql_cmd +    ' -i' + '"' + @install_path + '\install\instdist.sql"' + 
  10853.                                                 ' -o' + '"' + @install_path + '\install\instdist.out"'            
  10854.  
  10855.                 if (@osql_for_nt = 1)
  10856.                     select @osql_cmd = @osql_cmd + ' "'
  10857.  
  10858.                  exec @retcode = master..xp_cmdshell @osql_cmd
  10859.                 if @retcode <> 0 or @@error <> 0
  10860.                 begin
  10861.                     raiserror (14113, 16, -1, @osql_cmd, 'instdist.out')
  10862.                 end
  10863.                 
  10864.                 -- now add unique indexes in this distribution database
  10865.                 exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_distdb')
  10866.                 if @@error <> 0
  10867.                     return(1)
  10868.  
  10869.                 fetch next from cur_distdb into @dbname
  10870.             end
  10871.             close cur_distdb
  10872.             deallocate cur_distdb
  10873.  
  10874.             -- Upgrade replication settings/tables in MSDB database
  10875.             -- ONLY FOR DISTRIBUTORS
  10876.             exec @retcode = msdb.dbo.sp_vupgrade_replmsdb
  10877.             if @retcode <> 0 or @@error <> 0
  10878.                     return (1)
  10879.  
  10880.         end
  10881.  
  10882.         -- Note: place calls to procs for any schema or metadata changes required in else block here
  10883.     
  10884.         -- Update subscription database schema. This will upgrade tran subscriber changes as well as ALL merge system tables 
  10885.         -- As of 1/26/99 there are no changes needed for tran publisher tables
  10886.  
  10887.         exec @retcode = dbo.sp_vupgrade_subscription_databases
  10888.         if @retcode <> 0 or @@error <> 0
  10889.             return (1)
  10890.         
  10891.     end
  10892.  
  10893.     return (0)
  10894.  
  10895. end
  10896. go
  10897.  
  10898. exec dbo.sp_MS_marksystemobject sp_vupgrade_replication
  10899. go
  10900.  
  10901.  
  10902. raiserror('Creating procedure sp_vupgrade_distdb', 0,1)
  10903. go
  10904. create procedure sp_vupgrade_distdb 
  10905. as
  10906. /*
  10907. ** used to upgrade replication settings/tables in each distribution database
  10908. */
  10909.  
  10910. -- this raiserror makes sp_vupgrade_replication.out file easier to read
  10911. raiserror('sp_vupgrade_distdb', 0,1)
  10912.  
  10913.  
  10914. DECLARE @table_name sysname
  10915.  
  10916. --    MSrepl_version
  10917.     SELECT @table_name = N'MSrepl_version'
  10918.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSrepl_version' )
  10919.     BEGIN
  10920.         IF EXISTS ( SELECT major_version, minor_version, revision
  10921.             FROM MSrepl_version
  10922.             GROUP BY major_version, minor_version, revision
  10923.             HAVING COUNT(*) > 1 )
  10924.             RAISERROR (21144, 10, 9, @table_name)
  10925.         ELSE    
  10926.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSrepl_version' AND
  10927.                 id = OBJECT_ID('MSrepl_version') )
  10928.                 CREATE UNIQUE CLUSTERED INDEX ucMSrepl_version ON dbo.MSrepl_version
  10929.                     (major_version, minor_version, revision)
  10930.     END    
  10931.  
  10932.  
  10933. --    MSsnapshot_history
  10934.     SELECT @table_name = N'MSsnapshot_history'
  10935.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSsnapshot_history' )
  10936.     BEGIN
  10937.         IF EXISTS ( SELECT agent_id, timestamp, start_time, time
  10938.             FROM MSsnapshot_history
  10939.             GROUP BY agent_id, timestamp, start_time, time
  10940.             HAVING COUNT(*) > 1 )
  10941.             RAISERROR (21144, 10, 10, @table_name)
  10942.         ELSE        
  10943.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSsnapshot_history' AND 
  10944.                 id = OBJECT_ID('MSsnapshot_history'))
  10945.             BEGIN 
  10946.                 DROP INDEX dbo.MSsnapshot_history.ucMSsnapshot_history
  10947.                 CREATE UNIQUE CLUSTERED INDEX ucMSsnapshot_history ON dbo.MSsnapshot_history
  10948.                        (agent_id, timestamp, start_time, time)
  10949.             END
  10950.     END
  10951.  
  10952.  
  10953. --    MSlogreader_history
  10954.     SELECT @table_name = N'MSlogreader_history'
  10955.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSlogreader_history' )
  10956.     BEGIN
  10957.         IF EXISTS ( SELECT agent_id, timestamp, runstatus, start_time, time
  10958.             FROM MSlogreader_history
  10959.             GROUP BY agent_id, timestamp, runstatus, start_time, time
  10960.             HAVING COUNT(*) > 1 )
  10961.             RAISERROR (21144, 10, 11, @table_name)
  10962.         ELSE
  10963.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSlogreader_history' AND 
  10964.                 id = OBJECT_ID('MSlogreader_history'))
  10965.             BEGIN 
  10966.                 DROP INDEX dbo.MSlogreader_history.ucMSlogreader_history
  10967.                 CREATE UNIQUE CLUSTERED INDEX ucMSlogreader_history ON dbo.MSlogreader_history
  10968.                       (agent_id, timestamp, runstatus, start_time, time)
  10969.             END
  10970.     END
  10971.     
  10972.  
  10973. --    MSdistribution_history
  10974.     SELECT @table_name = N'MSdistribution_history'
  10975.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSdistribution_history' )
  10976.     BEGIN
  10977.         IF EXISTS ( SELECT agent_id, timestamp, runstatus, start_time, time
  10978.             FROM MSdistribution_history
  10979.             GROUP BY agent_id, timestamp, runstatus, start_time, time
  10980.             HAVING COUNT(*) > 1 )
  10981.             RAISERROR (21144, 10, 12, @table_name)
  10982.         ELSE
  10983.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSdistribution_history' AND 
  10984.                 id = OBJECT_ID('MSdistribution_history'))
  10985.             BEGIN 
  10986.                 DROP INDEX dbo.MSdistribution_history.ucMSdistribution_history
  10987.                 CREATE UNIQUE CLUSTERED INDEX ucMSdistribution_history ON dbo.MSdistribution_history
  10988.                  (agent_id, timestamp, runstatus, start_time, time)
  10989.             END
  10990.     END
  10991.     
  10992. --    MSmerge_history
  10993.     SELECT @table_name = N'MSmerge_history'
  10994.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_history' )
  10995.     BEGIN
  10996.         IF EXISTS ( SELECT agent_id, timestamp, runstatus, start_time, time
  10997.             FROM MSmerge_history
  10998.             GROUP BY agent_id, timestamp, runstatus, start_time, time
  10999.             HAVING COUNT(*) > 1 )
  11000.             RAISERROR (21144, 10, 13, @table_name)
  11001.         ELSE
  11002.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSmerge_history' AND 
  11003.                 id = OBJECT_ID('MSmerge_history'))
  11004.             BEGIN
  11005.                 DROP INDEX dbo.MSmerge_history.ucMSmerge_history
  11006.                 CREATE UNIQUE CLUSTERED INDEX ucMSmerge_history ON dbo.MSmerge_history
  11007.                   (agent_id, timestamp, runstatus, start_time, time)
  11008.             END
  11009.     END
  11010.     
  11011.  
  11012. --    MSsnapshot_agents
  11013.     SELECT @table_name = N'MSsnapshot_agents'
  11014.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSsnapshot_agents' )
  11015.     BEGIN
  11016.         IF EXISTS ( SELECT id
  11017.             FROM MSsnapshot_agents
  11018.             GROUP BY id
  11019.             HAVING COUNT(*) > 1 )
  11020.             RAISERROR (21144, 10, 14, @table_name)
  11021.         ELSE
  11022.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'iMSsnapshot_agents' AND 
  11023.                 id = OBJECT_ID('MSsnapshot_agents'))
  11024.             BEGIN
  11025.                 DROP INDEX dbo.MSsnapshot_agents.iMSsnapshot_agents
  11026.                 CREATE UNIQUE INDEX iMSsnapshot_agents ON dbo.MSsnapshot_agents    (id)
  11027.             END
  11028.     END
  11029.  
  11030. --    MSlogreader_agents
  11031.     SELECT @table_name = N'MSlogreader_agents'
  11032.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSlogreader_agents' )
  11033.     BEGIN
  11034.         IF EXISTS ( SELECT id
  11035.             FROM MSlogreader_agents
  11036.             GROUP BY id
  11037.             HAVING COUNT(*) > 1 )
  11038.             RAISERROR (21144, 10, 15, @table_name)
  11039.         ELSE
  11040.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'iMSlogreader_agents' AND 
  11041.                 id = OBJECT_ID('MSlogreader_agents'))
  11042.             BEGIN
  11043.                 DROP INDEX dbo.MSlogreader_agents.iMSlogreader_agents
  11044.                 CREATE UNIQUE INDEX iMSlogreader_agents ON dbo.MSlogreader_agents (id)
  11045.             END
  11046.     END
  11047.     
  11048. --    MSdistribution_agents
  11049.     SELECT @table_name = N'MSdistribution_agents'
  11050.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSdistribution_agents' )
  11051.     BEGIN
  11052.         IF EXISTS ( SELECT id
  11053.             FROM MSdistribution_agents
  11054.             GROUP BY id
  11055.             HAVING COUNT(*) > 1 )
  11056.             RAISERROR (21144, 10, 16, @table_name)
  11057.         ELSE
  11058.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSdistribution_agents' AND 
  11059.                 id = OBJECT_ID('MSdistribution_agents'))
  11060.             BEGIN
  11061.                 DROP INDEX dbo.MSdistribution_agents.ucMSdistribution_agents
  11062.                 CREATE UNIQUE CLUSTERED INDEX ucMSdistribution_agents ON dbo.MSdistribution_agents (id)
  11063.             END
  11064.     END
  11065.  
  11066.  
  11067. --    MSmerge_agents
  11068.     SELECT @table_name = N'MSmerge_agents'
  11069.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_agents' )
  11070.     BEGIN
  11071.         IF EXISTS ( SELECT id
  11072.             FROM MSmerge_agents
  11073.             GROUP BY id
  11074.             HAVING COUNT(*) > 1 )
  11075.             RAISERROR (21144, 10, 17, @table_name)
  11076.         ELSE
  11077.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'iMSmerge_agents' AND 
  11078.                 id = OBJECT_ID('MSmerge_agents'))
  11079.             BEGIN
  11080.                 DROP INDEX dbo.MSmerge_agents.iMSmerge_agents
  11081.                 CREATE UNIQUE INDEX iMSmerge_agents ON dbo.MSmerge_agents (id)
  11082.             END
  11083.     END
  11084.     
  11085.  
  11086. --    MSpublication_access
  11087.     SELECT @table_name = N'MSpublication_access'
  11088.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSpublication_access' )
  11089.     BEGIN
  11090.         IF EXISTS ( SELECT publication_id, login
  11091.             FROM MSpublication_access
  11092.             GROUP BY publication_id, login
  11093.             HAVING COUNT(*) > 1 )
  11094.             RAISERROR (21144, 10, 18, @table_name)
  11095.         ELSE
  11096.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSpublication_access' AND 
  11097.                 id = OBJECT_ID('MSpublication_access'))
  11098.             BEGIN
  11099.                 DROP INDEX dbo.MSpublication_access.ucMSpublication_access
  11100.                 CREATE UNIQUE CLUSTERED INDEX ucMSpublication_access ON dbo.MSpublication_access
  11101.                     (publication_id, login)
  11102.             END
  11103.     END
  11104. go
  11105.  
  11106. exec dbo.sp_MS_marksystemobject sp_vupgrade_distdb
  11107. go
  11108.  
  11109.  
  11110. raiserror('Creating procedure sp_vupgrade_replmsdb', 0,1)
  11111. go
  11112. create procedure sp_vupgrade_replmsdb 
  11113. as
  11114. /*
  11115. ** used to upgrade replication settings/tables in MSDB database
  11116. */
  11117.  
  11118. -- this raiserror makes sp_vupgrade_replication.out file easier to read
  11119. raiserror('sp_vupgrade_replmsdb', 0,1)
  11120.  
  11121.  
  11122.     DECLARE @table_name sysname
  11123.  
  11124.  
  11125. --    MSdistpublishers
  11126.     SELECT @table_name = N'MSdistpublishers'
  11127.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSdistpublishers' ) 
  11128.     BEGIN
  11129.         IF EXISTS ( SELECT name
  11130.             FROM MSdistpublishers
  11131.             GROUP BY name 
  11132.             HAVING COUNT(*) > 1 )
  11133.             RAISERROR (21144, 10, 19, @table_name)
  11134.         ELSE
  11135.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSdistpublishers' AND
  11136.                 id = OBJECT_ID('MSdistpublishers') )
  11137.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistpublishers ON msdb.dbo.MSdistpublishers(name)
  11138.     END
  11139.     
  11140. --    MSdistributiondbs
  11141.     SELECT @table_name = N'MSdistributiondbs'
  11142.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSdistributiondbs' )
  11143.     BEGIN
  11144.         IF EXISTS ( SELECT name
  11145.             FROM MSdistributiondbs
  11146.             GROUP BY name 
  11147.             HAVING COUNT(*) > 1 )
  11148.             RAISERROR (21144, 10, 20, @table_name)            
  11149.         ELSE                
  11150.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSdistributiondbs' AND
  11151.                 id = OBJECT_ID('MSdistributiondbs') )
  11152.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistributiondbs ON msdb.dbo.MSdistributiondbs(name)
  11153.     END
  11154.     
  11155. --    MSdistributor
  11156.     SELECT @table_name = N'MSdistributor'
  11157.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSdistributor' )
  11158.     BEGIN
  11159.         IF EXISTS ( SELECT property
  11160.             FROM MSdistributor
  11161.             GROUP BY property 
  11162.             HAVING COUNT(*) > 1 )
  11163.             RAISERROR (21144, 10, 21, @table_name)            
  11164.         ELSE                    
  11165.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSdistributor' AND
  11166.                 id = OBJECT_ID('MSdistributor') )
  11167.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistributor ON msdb.dbo.MSdistributor(property)
  11168.     END    
  11169. go
  11170.  
  11171.  
  11172. exec dbo.sp_MS_marksystemobject sp_vupgrade_replmsdb
  11173. go
  11174.  
  11175. raiserror('Creating procedure sp_restoredbreplication', 0,1)
  11176. go
  11177.  
  11178. create procedure sp_restoredbreplication ( @srv_orig sysname, @db_orig sysname )
  11179. as 
  11180. /*
  11181.  * used by restore process to strip out replication settings if restoring to non-originating
  11182.  * server/db or system otherwise not capable of keeping replication working
  11183.  * WARNING : procs called here run internal to server and must be owner qualified
  11184. */
  11185. begin
  11186.  
  11187.     set nocount on
  11188.  
  11189.     -- db bits
  11190.     declare @db_tranbit int
  11191.     declare @db_mergbit int
  11192.     declare @db_distbit int
  11193.     select @db_tranbit = 1, @db_mergbit = 4, @db_distbit = 16
  11194.  
  11195.     declare @repl_installed bit -- repl procs installed flag
  11196.     declare @remove_repl bit    -- remove replication flag ; remove on true (1)
  11197.     declare @restoreoverride int
  11198.     declare @db_curr sysname
  11199.     DECLARE @retcode int
  11200.     DECLARE @proc nvarchar(255)
  11201.  
  11202.     -- Support override of replication remove on attach and restore
  11203.     select @proc = 'master.dbo.xp_regread '
  11204.     execute @retcode = @proc    'HKEY_LOCAL_MACHINE', 
  11205.                                 'SOFTWARE\Microsoft\MSSQLServer\Replication',
  11206.                                 'RestoreOverride',
  11207.                                 @param = @restoreoverride output,
  11208.                                 @no_output = 'no_output'
  11209.  
  11210.     if ( @@error = 0 ) and ( @retcode = 0 )
  11211.     begin
  11212.         -- ReplRestoreOverride = 1 = user elects to take no cleanup on restore or attach
  11213.         if ( isnull( @restoreoverride, 0 ) = 1 )
  11214.             return(0)
  11215.     end
  11216.     
  11217.         
  11218.     select @remove_repl = 0, @repl_installed = 1 
  11219.  
  11220.     select @db_curr = db_name() 
  11221.  
  11222.     -- check server has replication installed; if not, we cannot remove replication; this should be benign
  11223.     if not exists ( select * from master..MSreplication_options 
  11224.                         where optname = 'transactional' 
  11225.                            or optname = 'merge' )
  11226.         select @repl_installed = 0
  11227.  
  11228.     -- check restore to same server/db backed up
  11229.     if ( UPPER(@srv_orig) <> UPPER(@@SERVERNAME) ) or ( @db_orig <> @db_curr ) 
  11230.         select @remove_repl = 1
  11231.  
  11232.     -- subscribing dbs are assumed ok
  11233.     -- distribution dbs are assumed ok
  11234.  
  11235.     -- publishing db check : transactional : requires coordinated restore of dist db - no way to check
  11236.     if ( 
  11237.             exists( select * from sysobjects where name = 'syspublications' )
  11238.             -- exists( select * from syspublications ) 
  11239.             and not exists( select * from master..sysdatabases 
  11240.                 where name = @db_orig and category & @db_tranbit = @db_tranbit )
  11241.         )
  11242.     begin
  11243.         -- publications exist in db, but db on server is not published; 
  11244.         -- unpublish the db, ignoring distributor cleanup
  11245.  
  11246.         update master.dbo.sysdatabases set category = category | @db_tranbit where name = @db_curr
  11247.         exec dbo.sp_MSpublishdb 'false', 1
  11248.         update master.dbo.sysdatabases set category = category & ~@db_tranbit where name = @db_curr
  11249.  
  11250.         -- we've already brute force stripped replication from the db, 
  11251.         -- don't call sp_removedbreplication at proc exit
  11252.  
  11253.     end
  11254.  
  11255.     if ( @repl_installed = 1 ) and ( @remove_repl = 1 ) 
  11256.         exec dbo.sp_removedbreplication @db_curr
  11257.  
  11258.  
  11259. end
  11260. go
  11261.  
  11262. exec dbo.sp_MS_marksystemobject sp_restoredbreplication
  11263. go
  11264.  
  11265. raiserror('Creating procedure sp_MSget_publisher_rpc', 0,1)
  11266. GO
  11267.  
  11268. CREATE PROCEDURE sp_MSget_publisher_rpc
  11269.         @trigger_id int,
  11270.         @connect_string nvarchar(2000) output
  11271.     AS
  11272.  
  11273.     SET NOCOUNT ON
  11274.     
  11275.     declare @publisher sysname
  11276.     declare @publisher_db sysname
  11277.     declare @login sysname
  11278.     declare @password sysname
  11279.     declare @security_mode int
  11280.     declare @object_id int
  11281.     declare @retcode int
  11282.  
  11283.     -- Make sure this proc is called from the trigger.
  11284.     -- Better to use object_id if owner name is passed in.
  11285.     if trigger_nestlevel(@trigger_id) = 0
  11286.     begin
  11287.         raiserror(14126, 16, -1)
  11288.         return (1) -- current user does not have insert permission to underlying table
  11289.     end
  11290.  
  11291.     -- Get security from property table, if nothing find, the rpc will fail.
  11292.     IF EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  11293.     begin
  11294.         select @login = publisher_login,
  11295.             @password = publisher_password,
  11296.             @security_mode = publisher_security_mode,
  11297.             @publisher = o.publisher,
  11298.             @publisher_db = o.publisher_db
  11299.          from MSsubscription_properties p, MSreplication_objects o
  11300.         where o.object_name = object_name(@trigger_id) 
  11301.         and UPPER(p.publisher) = UPPER(o.publisher)
  11302.         and p.publisher_db = p.publisher_db
  11303.         and p.publication = o.publication
  11304.  
  11305.         EXEC @retcode = master.dbo.xp_repl_encrypt @password OUTPUT
  11306.         IF @@error <> 0 OR @retcode <> 0
  11307.             return 1
  11308.  
  11309.     end
  11310.     else
  11311.     begin
  11312.         -- RPC security info invalid
  11313.         raiserror(21079, 16, -1)
  11314.         return(1)
  11315.     end
  11316.     
  11317.     if @security_mode = 2 -- 2 = use sysservers
  11318.     begin
  11319.         select @connect_string = null
  11320.     end
  11321.     else
  11322.     begin
  11323.         if @login is null
  11324.         begin
  11325.             -- RPC security info invalid
  11326.             raiserror(21079, 16, -1)
  11327.             return(1)
  11328.         end
  11329.  
  11330.         if @password is null
  11331.             select @password = N''
  11332.         -- Names containing space in connection string is automatically enabled.
  11333.         -- [] and ' are not recoginized by opendatasource
  11334.         -- Note ';' in names in connection string will mess things up.
  11335.         select @connect_string = 'SERVER=' + @publisher + ';UID=' + 
  11336.             @login + ';PWD=' + @password + ';'
  11337.     end
  11338. GO
  11339.  
  11340. raiserror('Creating procedure sp_link_publication', 0,1)
  11341. GO
  11342.  
  11343. CREATE PROCEDURE sp_link_publication
  11344.     @publisher      sysname,            -- publishing server name
  11345.     @publisher_db   sysname,            -- publishing database name. If NULL then same as current db
  11346.     @publication    sysname,            -- publication name
  11347.     @security_mode  int,                -- 0 = standard; 2 = static linked server entry
  11348.     @login            sysname = NULL,
  11349.     @password        sysname = NULL
  11350. AS
  11351.     set nocount on
  11352.     declare @retcode int
  11353.     
  11354.     --  Security Check
  11355.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  11356.     IF @@ERROR <> 0 or @retcode <> 0
  11357.     RETURN(1)
  11358.  
  11359.     -- Parameter check: @security_mode
  11360.     if @security_mode <> 0 and @security_mode <> 2
  11361.     begin
  11362.         RAISERROR(21055, 16, -1, '@security_mode','sp_link_publication')
  11363.         RETURN (1)
  11364.     end
  11365.  
  11366.     if @security_mode = 2 and not exists (select * from master..sysservers where
  11367.         UPPER(srvname) = UPPER(@publisher))
  11368.     begin
  11369.         declare @len int
  11370.         select @len = len(@publisher) * 2
  11371.         RAISERROR(7202, 16, -1, @len ,@publisher)
  11372.         RETURN (1)
  11373.     end
  11374.  
  11375.     IF @password = N''
  11376.         select @password = NULL
  11377.  
  11378.     /* 
  11379.     ** Check to see if MSsubscription_properties table exists.
  11380.     ** If not, create it.
  11381.     */
  11382.     exec @retcode = dbo.sp_MScreate_sub_tables
  11383.     IF @@ERROR <> 0 or @retcode <> 0
  11384.         return 1
  11385.  
  11386.     -- Encrypt the password
  11387.     EXEC @retcode = master.dbo.xp_repl_encrypt @password OUTPUT
  11388.     IF @@error <> 0 OR @retcode <> 0
  11389.         return 1
  11390.  
  11391.     IF NOT EXISTS (select * from MSsubscription_properties 
  11392.             where UPPER(publisher) = UPPER(@publisher)
  11393.                 and publisher_db =  @publisher_db
  11394.                 and publication = @publication) 
  11395.     BEGIN
  11396.         INSERT INTO MSsubscription_properties 
  11397.             (publisher, publisher_db, publication, publication_type, 
  11398.              publisher_login,publisher_password, publisher_security_mode, 
  11399.              distributor, distributor_login, distributor_password, 
  11400.              distributor_security_mode)
  11401.         values (@publisher, @publisher_db, @publication, 0,    @login, @password, 
  11402.             @security_mode, NULL, NULL, NULL, 1)
  11403.     END
  11404.     ELSE
  11405.     BEGIN
  11406.         update MSsubscription_properties set
  11407.             publisher_login = @login,
  11408.             publisher_password = @password,
  11409.             publisher_security_mode = @security_mode
  11410.             where UPPER(publisher) = UPPER(@publisher)
  11411.                 and publisher_db =  @publisher_db
  11412.                 and publication = @publication
  11413.     END
  11414. go
  11415.  
  11416. raiserror('Creating procedure sp_MScreate_sub_tables', 0,1)
  11417. GO
  11418.  
  11419. CREATE PROCEDURE sp_MScreate_sub_tables (
  11420. @tran_sub_table bit = 0,
  11421. @property_table bit = 1
  11422. )
  11423. as
  11424.     set nocount on
  11425.     declare @retcode int
  11426.  
  11427.     IF @tran_sub_table = 1 and
  11428.         (NOT EXISTS (SELECT * FROM sysobjects WHERE 
  11429.         type = 'U' AND name = 'MSreplication_subscriptions')) 
  11430.     BEGIN
  11431.         CREATE TABLE dbo.MSreplication_subscriptions
  11432.         (
  11433.         publisher sysname NOT NULL,
  11434.         publisher_db sysname NOT NULL, 
  11435.         publication sysname NULL, 
  11436.         independent_agent bit NOT NULL,
  11437.         subscription_type int NOT NULL,
  11438.         distribution_agent nvarchar (100) NULL, 
  11439.         time smalldatetime NOT NULL,
  11440.         description nvarchar(255) NULL,
  11441.         transaction_timestamp varbinary(16) NOT NULL,
  11442.         -- SyncTran
  11443.         update_mode tinyint NOT NULL,
  11444.         agent_id binary(16) NULL,
  11445.         subscription_guid binary(16) NULL,
  11446.         subid binary(16) NULL,
  11447.         immediate_sync bit NOT NULL default 1 -- sync_mode with a default of 1
  11448.         )
  11449.         IF @@ERROR <> 0
  11450.             GOTO UNDO
  11451.  
  11452.         CREATE UNIQUE CLUSTERED INDEX uc1MSReplication_subscriptions ON
  11453.                         MSreplication_subscriptions(publication, publisher_db, publisher, subscription_type)
  11454.         IF @@ERROR <> 0
  11455.             GOTO UNDO
  11456.  
  11457.          EXEC dbo.sp_MS_marksystemobject 'MSreplication_subscriptions'
  11458.          IF @@ERROR <> 0
  11459.             GOTO UNDO
  11460.     END    
  11461.  
  11462.     IF @property_table = 1 and
  11463.         NOT EXISTS (SELECT * FROM sysobjects WHERE 
  11464.         type = 'U' AND
  11465.         name = 'MSsubscription_properties')
  11466.     BEGIN
  11467.         BEGIN TRAN
  11468.  
  11469.         CREATE TABLE dbo.MSsubscription_properties
  11470.         (
  11471.         publisher                        sysname        NOT NULL,
  11472.         publisher_db                    sysname        NOT NULL,
  11473.         publication                        sysname        NOT NULL,
  11474.         publication_type                int            NOT NULL,
  11475.         publisher_login                    sysname        NULL,
  11476.         publisher_password                sysname        NULL,
  11477.         publisher_security_mode            int            NOT NULL,
  11478.         distributor                        sysname        NULL,
  11479.         distributor_login                sysname        NULL,
  11480.         distributor_password            sysname        NULL,
  11481.         distributor_security_mode        int            NOT NULL,
  11482.         ftp_address                        sysname        NULL,
  11483.         ftp_port                        int            NULL,
  11484.         ftp_login                        sysname        NULL,
  11485.         ftp_password                    sysname        NULL,
  11486.         )
  11487.         IF @@ERROR <> 0
  11488.             GOTO UNDO
  11489.  
  11490.         CREATE UNIQUE CLUSTERED INDEX uc1MSsubscription_properties ON
  11491.                         MSsubscription_properties(publication, publisher_db, publisher)
  11492.         IF @@ERROR <> 0
  11493.             GOTO UNDO
  11494.         
  11495.         EXEC @retcode = dbo.sp_MS_marksystemobject 'MSsubscription_properties'
  11496.         if @retcode <> 0 or @@error <> 0
  11497.             GOTO UNDO
  11498.  
  11499.         COMMIT TRAN
  11500.     end
  11501.  
  11502.     return(0)
  11503.     
  11504. UNDO:
  11505.     IF @@TRANCOUNT = 1
  11506.         ROLLBACK TRAN
  11507.     ELSE
  11508.         COMMIT TRAN  
  11509.     return(1) 
  11510. go
  11511.  
  11512. exec dbo.sp_MS_marksystemobject sp_MScreate_sub_tables
  11513. go
  11514.  
  11515. raiserror('Creating procedure sp_MS_replication_installed', 0,1)
  11516. GO
  11517.  
  11518. CREATE PROCEDURE sp_MS_replication_installed
  11519. as
  11520.     set nocount on
  11521.  
  11522.     declare @isinstalled int
  11523.     select @isinstalled = 0
  11524.     
  11525.     create table #keyvalues (keyvalue nvarchar(255) NOT NULL, keyvaluedata nvarchar(255) null)
  11526.  
  11527.     insert into #keyvalues exec master..xp_regenumvalues 'HKEY_LOCAL_MACHINE',
  11528.         'SOFTWARE\Microsoft\MSSQLServer\Replication'
  11529.     
  11530.     if @@ERROR <> 0
  11531.     begin
  11532.         drop table #keyvalues
  11533.         return (-1)
  11534.     end
  11535.  
  11536.     select @isinstalled = convert (int, (select keyvaluedata from #keyvalues where keyvalue = N'IsInstalled'))
  11537.     
  11538.     drop table #keyvalues
  11539.  
  11540.     if (@isinstalled is null or @isinstalled = 0)
  11541.     begin
  11542.         raiserror (21028, 16, -1)
  11543.         return (0)
  11544.     end
  11545.  
  11546.     return (1)
  11547. go
  11548. exec dbo.sp_MS_marksystemobject sp_MS_replication_installed
  11549. go
  11550.  
  11551. raiserror('Creating procedure sp_MSunc_to_drive', 0,1)
  11552. GO
  11553.  
  11554. CREATE PROCEDURE sp_MSunc_to_drive (
  11555.         @unc_path nvarchar(255), 
  11556.         @local_server sysname, 
  11557.         @local_path nvarchar(255) output
  11558.         )
  11559.     AS
  11560.  
  11561.     SET NOCOUNT ON
  11562.  
  11563.     declare @pattern nvarchar(150)
  11564.  
  11565.     select @pattern = N'\\' + upper(@local_server) + N'\'
  11566.  
  11567.     if    charindex(@pattern, upper(substring(@unc_path, 1, len(@pattern)))) <> 0 
  11568.         and charindex(N'$\', substring(@unc_path, len(@pattern)+2, 2))<>0
  11569.         select @local_path = substring(@unc_path, len(@pattern) + 1, 1) + N':' +
  11570.             substring(@unc_path, len(@pattern) + 3, len(@unc_path) - len(@pattern) -1)
  11571.     else
  11572.         select @local_path = @unc_path
  11573. GO
  11574. exec dbo.sp_MS_marksystemobject sp_MSunc_to_drive
  11575. go
  11576.  
  11577.  
  11578. raiserror('Creating procedure sp_MSrepl_linkedservers_rowset', 0,1)
  11579. GO
  11580. create proc sp_MSrepl_linkedservers_rowset @srvname sysname
  11581. as
  11582.     select
  11583.         SVR_NAME         = srvname,
  11584.         SVR_PRODUCT        = srvproduct,
  11585.         SVR_PROVIDERNAME    = providername,
  11586.         SVR_DATASOURCE        = datasource,
  11587.         SVR_PROVIDERSTRING    = providerstring,
  11588.         SVR_LOCATION        = location,
  11589.         SVR_CATALOG        = catalog
  11590.     from master.dbo.sysservers
  11591.     where UPPER(srvname) = UPPER(@srvname) and 
  11592.     isnull(providername,' ') <> ' ' and
  11593.     ( isnull(datasource, ' ') <> ' ' or
  11594.     isnull(location, ' ') <> ' ' or
  11595.     isnull(providerstring, ' ') <> ' '  or
  11596.     isnull(catalog, ' ') <> ' ' )
  11597.     order by 1    
  11598. go
  11599. exec dbo.sp_MS_marksystemobject sp_MSrepl_linkedservers_rowset
  11600. go
  11601.  
  11602. raiserror('Creating procedure sp_MSget_qualified_name', 0,1)
  11603. GO
  11604. CREATE PROCEDURE sp_MSget_qualified_name (
  11605.     @object_id                int,                         
  11606.     @qualified_name            nvarchar(512)    output       
  11607. )AS
  11608.     select @qualified_name = quotename(user_name(OBJECTPROPERTY(@object_id,'OwnerId'))) + 
  11609.         N'.' + quotename(object_name(@object_id))
  11610. GO
  11611. exec dbo.sp_MS_marksystemobject sp_MSget_qualified_name
  11612. go
  11613.  
  11614. raiserror('Creating procedure sp_MSdrop_object', 0,1)
  11615. GO
  11616.  
  11617. CREATE PROCEDURE sp_MSdrop_object (
  11618.         @object_id int = NULL,
  11619.         @object_name sysname = NULL,
  11620.         @object_owner sysname = NULL
  11621.         )
  11622.     AS
  11623.  
  11624.     SET NOCOUNT ON
  11625.  
  11626.     declare @cmd nvarchar(1000)
  11627.     
  11628.     if @object_name is not null
  11629.     begin
  11630.         declare @owner_id int
  11631.         if @object_owner is null
  11632.             select @owner_id = user_id()
  11633.         else
  11634.             select @owner_id = user_id(@object_owner)
  11635.         select @object_id = id from sysobjects where
  11636.             name = @object_name and
  11637.             uid = @owner_id
  11638.        end
  11639.  
  11640.        if @object_id is not null
  11641.        begin
  11642.            exec dbo.sp_MSget_qualified_name @object_id, @cmd output
  11643.            if objectproperty(@object_id, 'IsTable') = 1
  11644.                select @cmd = 'drop table ' + @cmd
  11645.            else if objectproperty(@object_id, 'IsProcedure') = 1
  11646.                select @cmd = 'drop procedure ' + @cmd
  11647.            else if objectproperty(@object_id, 'IsTrigger') = 1
  11648.                select @cmd = 'drop trigger ' + @cmd
  11649.            else if objectproperty(@object_id, 'IsView') = 1
  11650.                select @cmd = 'drop view ' + @cmd
  11651.        end
  11652.  
  11653.        exec (@cmd)
  11654.        if @@error <> 0
  11655.            return(1)
  11656.  
  11657. GO
  11658.  
  11659. raiserror('Creating procedure sp_MSregistersubscription', 0,1)
  11660. go
  11661.  
  11662. CREATE PROCEDURE sp_MSregistersubscription (
  11663.     @replication_type            int, /* Transactional = 1, Merge = 2 */
  11664.     @publisher                     sysname,
  11665.     @publisher_db                 sysname,
  11666.     @publisher_security_mode    int = NULL,                        /* 0 standard; 1 integrated */
  11667.     @publisher_login            sysname = NULL,
  11668.     @publisher_password    sysname = NULL,
  11669.     @publication                 sysname,         
  11670.     @subscriber                 sysname,
  11671.     @subscriber_db                 sysname,
  11672.     @subscriber_security_mode    int = NULL,                        /* 0 standard; 1 integrated */
  11673.     @subscriber_login            sysname = NULL,
  11674.     @subscriber_password    sysname = NULL,
  11675.     @distributor                 sysname,
  11676.     @distributor_security_mode     int = NULL,
  11677.     @distributor_login             sysname = NULL,
  11678.     @distributor_password    sysname = NULL,
  11679.     @subscription_id            uniqueidentifier ,
  11680.     @independent_agent            int = NULL,
  11681.     @subscription_type            int
  11682.     ) AS
  11683.  
  11684.     SET NOCOUNT ON
  11685.  
  11686.     /* MobileSync Support */
  11687.     declare @subscription_name                nvarchar(1000)
  11688.     declare @regkey                            nvarchar(1000)
  11689.     declare @subidstr                        nvarchar(38)
  11690.     declare @profile_name                     nvarchar(100)
  11691.     declare @retcode                        int
  11692.     declare @publisher_encrypted_password    sysname
  11693.     declare @subscriber_encrypted_password    sysname
  11694.     declare @distributor_encrypted_password    sysname
  11695.     declare @temp_binary_password            varbinary(256)
  11696.  
  11697.     set @subscription_name = @publisher + ':' + @publisher_db + ':' + @publication + ':' + @subscriber + ':' + @subscriber_db
  11698.     /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  11699.     set @subscription_name = REPLACE(@subscription_name,'\','/')
  11700.     set @regkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\' + @subscription_name
  11701.     set @subidstr = '{' + convert ( nchar(36), @subscription_id) + '}'
  11702.     set @profile_name = formatmessage(20550) -- SyncMgr Profile
  11703.  
  11704.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11705.                                @regkey,
  11706.                                'ProfileName',
  11707.                                'REG_SZ',
  11708.                                 @profile_name    
  11709.     if @retcode <> 0 OR @@ERROR <> 0
  11710.         return 1
  11711.  
  11712.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11713.                                @regkey,
  11714.                                'ReplicationType',
  11715.                                'REG_DWORD',
  11716.                                 @replication_type    
  11717.     if @retcode <> 0 OR @@ERROR <> 0
  11718.         return 1
  11719.  
  11720.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11721.                                @regkey,
  11722.                                'SubscriptionType',
  11723.                                'REG_DWORD',
  11724.                                 @subscription_type    
  11725.     if @retcode <> 0 OR @@ERROR <> 0
  11726.         return 1
  11727.  
  11728.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11729.                                @regkey,
  11730.                                'Subid',
  11731.                                'REG_SZ',
  11732.                                 @subidstr    
  11733.     if @retcode <> 0 OR @@ERROR <> 0
  11734.         return 1
  11735.  
  11736.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11737.                                @regkey,
  11738.                                'Publisher',
  11739.                                'REG_SZ',
  11740.                                 @publisher                                        
  11741.     if @retcode <> 0 OR @@ERROR <> 0
  11742.         return 1
  11743.  
  11744.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11745.                                @regkey,
  11746.                                'PublisherDb',
  11747.                                'REG_SZ',
  11748.                                 @publisher_db
  11749.     if @retcode <> 0 OR @@ERROR <> 0
  11750.         return 1
  11751.  
  11752.     /* If Publisher security mode is NOT NULL, write out the entries */
  11753.     if @publisher_security_mode IS NOT NULL
  11754.         begin
  11755.                EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11756.                                        @regkey,
  11757.                                        'PublisherSecurityMode',
  11758.                                        'REG_DWORD',
  11759.                                         @publisher_security_mode
  11760.             if @retcode <> 0 OR @@ERROR <> 0
  11761.                 return 1
  11762.  
  11763.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11764.                                        @regkey,
  11765.                                        'PublisherLogin',
  11766.                                        'REG_SZ',
  11767.                                         @publisher_login                                    
  11768.             if @retcode <> 0 OR @@ERROR <> 0
  11769.                 return 1
  11770.  
  11771.             /* Encrypt the password before writing to the registry */
  11772.             set @publisher_encrypted_password = @publisher_password
  11773.             exec @retcode = master.dbo.xp_repl_encrypt @publisher_encrypted_password OUTPUT
  11774.             if @retcode <> 0 OR @@ERROR <> 0
  11775.                 return 1
  11776.  
  11777.             select @temp_binary_password = convert(varbinary(256), @publisher_encrypted_password)
  11778.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11779.                                        @regkey,
  11780.                                        'PublisherEncryptedPasswordBinary',
  11781.                                        'REG_BINARY',
  11782.                                         @temp_binary_password
  11783.             if @retcode <> 0 OR @@ERROR <> 0
  11784.                 return 1
  11785.  
  11786.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11787.                                        @regkey,
  11788.                                        'PublisherEncryptedPassword',
  11789.                                        'REG_SZ',
  11790.                                         @publisher_encrypted_password
  11791.             if @retcode <> 0 OR @@ERROR <> 0
  11792.                 return 1
  11793.         end
  11794.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11795.                                @regkey,
  11796.                                'Publication',
  11797.                                'REG_SZ',
  11798.                                 @publication
  11799.     if @retcode <> 0 OR @@ERROR <> 0
  11800.         return 1
  11801.  
  11802.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11803.                                @regkey,
  11804.                                'Subscriber',
  11805.                                'REG_SZ',
  11806.                                 @subscriber
  11807.     if @retcode <> 0 OR @@ERROR <> 0
  11808.         return 1
  11809.  
  11810.     /* If Subscriber security mode is NOT NULL, write out the entries */
  11811.     if @subscriber_security_mode IS NOT NULL
  11812.         begin
  11813.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11814.                                @regkey,
  11815.                                'SubscriberSecurityMode',
  11816.                                'REG_DWORD',
  11817.                                 @subscriber_security_mode
  11818.             if @retcode <> 0 OR @@ERROR <> 0
  11819.                 return 1
  11820.  
  11821.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11822.                                @regkey,
  11823.                                'SubscriberLogin',
  11824.                                'REG_SZ',
  11825.                                 @subscriber_login                                    
  11826.             if @retcode <> 0 OR @@ERROR <> 0
  11827.                 return 1
  11828.  
  11829.             /* Encrypt the password before writing to the registry */
  11830.             set @subscriber_encrypted_password = @subscriber_password
  11831.             exec @retcode = master.dbo.xp_repl_encrypt @subscriber_encrypted_password OUTPUT
  11832.             if @retcode <> 0 OR @@ERROR <> 0
  11833.                 return 1
  11834.  
  11835.             select @temp_binary_password = convert(varbinary(256), @subscriber_encrypted_password)
  11836.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11837.                                @regkey,
  11838.                                'SubscriberEncryptedPasswordBinary',
  11839.                                'REG_BINARY',
  11840.                                 @temp_binary_password
  11841.             if @retcode <> 0 OR @@ERROR <> 0
  11842.                 return 1
  11843.  
  11844.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11845.                                @regkey,
  11846.                                'SubscriberEncryptedPassword',
  11847.                                'REG_SZ',
  11848.                                 @subscriber_encrypted_password
  11849.             if @retcode <> 0 OR @@ERROR <> 0
  11850.                 return 1
  11851.         end
  11852.  
  11853.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11854.                                @regkey,
  11855.                                'SubscriberDb',
  11856.                                'REG_SZ',
  11857.                                 @subscriber_db                                    
  11858.     if @retcode <> 0 OR @@ERROR <> 0
  11859.         return 1
  11860.                 
  11861.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11862.                                @regkey,
  11863.                                'Distributor',
  11864.                                'REG_SZ',
  11865.                                 @distributor
  11866.     if @retcode <> 0 OR @@ERROR <> 0
  11867.         return 1
  11868.  
  11869.     /* If Distributor security mode is NOT NULL, write out the entries */
  11870.     if @distributor_security_mode IS NOT NULL
  11871.         begin
  11872.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11873.                                @regkey,
  11874.                                'DistributorSecurityMode',
  11875.                                'REG_DWORD',
  11876.                                 @distributor_security_mode
  11877.             if @retcode <> 0 OR @@ERROR <> 0
  11878.                 return 1
  11879.  
  11880.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11881.                                @regkey,
  11882.                                'DistributorLogin',
  11883.                                'REG_SZ',
  11884.                                 @distributor_login                                    
  11885.             if @retcode <> 0 OR @@ERROR <> 0
  11886.                 return 1
  11887.  
  11888.             /* Encrypt the password before writing to the registry */
  11889.             set @distributor_encrypted_password = @distributor_password
  11890.             exec @retcode = master.dbo.xp_repl_encrypt @distributor_encrypted_password OUTPUT
  11891.             if @retcode <> 0 OR @@ERROR <> 0
  11892.                 return 1
  11893.  
  11894.             select @temp_binary_password = convert(varbinary(256), @distributor_encrypted_password)
  11895.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11896.                                @regkey,
  11897.                                'DistributorEncryptedPasswordBinary',
  11898.                                'REG_BINARY',
  11899.                                 @temp_binary_password
  11900.             if @retcode <> 0 OR @@ERROR <> 0
  11901.                 return 1
  11902.  
  11903.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11904.                                @regkey,
  11905.                                'DistributorEncryptedPassword',
  11906.                                'REG_SZ',
  11907.                                 @distributor_encrypted_password
  11908.             if @retcode <> 0 OR @@ERROR <> 0
  11909.                 return 1
  11910.         end
  11911.     if @independent_agent IS NOT NULL
  11912.         begin
  11913.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11914.                                @regkey,
  11915.                                'IndependentAgent',
  11916.                                'REG_DWORD',
  11917.                                 @independent_agent    
  11918.             if @retcode <> 0 OR @@ERROR <> 0
  11919.                 return 1
  11920.         end                
  11921.     return 0
  11922. GO
  11923.  
  11924. raiserror('Creating procedure sp_MSunregistersubscription', 0,1)
  11925. go
  11926.  
  11927. CREATE PROCEDURE sp_MSunregistersubscription
  11928.         @publisher         sysname = NULL, 
  11929.         @publisher_db     sysname = NULL, 
  11930.         @publication     sysname = NULL, 
  11931.         @subscriber     sysname = NULL,
  11932.         @subscriber_db     sysname = NULL
  11933.     AS
  11934.  
  11935.     /* 
  11936.     ** Drop the corresponding registry entry for MobileSync
  11937.     */
  11938.     declare @subscription_name     nvarchar(1000)
  11939.     declare @regkey                nvarchar(1000)
  11940.     declare @retcode            int
  11941.     declare @keyexist            int
  11942.  
  11943.     set @subscription_name = @publisher + ':' + @publisher_db + ':' + @publication + ':' + @subscriber + ':' + @subscriber_db
  11944.     /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  11945.     set @subscription_name = REPLACE(@subscription_name,'\','/')
  11946.     set @regkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\' + @subscription_name
  11947.  
  11948.     create table #keyexist (keyexist int)
  11949.     insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @regkey
  11950.     select @keyexist = keyexist from #keyexist
  11951.     drop table #keyexist
  11952.     
  11953.     if @keyexist = 1
  11954.         begin
  11955.             EXECUTE @retcode = master.dbo.xp_regdeletekey 'HKEY_LOCAL_MACHINE', @regkey
  11956.             if @@error <> 0 OR @retcode <> 0
  11957.                 return 1
  11958.         end
  11959.     return 0        
  11960.  
  11961. GO
  11962.  
  11963. raiserror('Creating procedure sp_MSget_jobstate', 0,1)
  11964. go
  11965.  
  11966. -- Procedure sp_MSget_jobstate
  11967. --    The proc takes a specific Job ID and returns the Job State of the job
  11968. --        Returns a row with one column job_state
  11969. --        Returns a row with NULL if job does not exist
  11970. -- 
  11971.  
  11972. CREATE PROCEDURE sp_MSget_jobstate
  11973.     @job_id             UNIQUEIDENTIFIER
  11974. AS
  11975. BEGIN
  11976.     DECLARE @is_sysadmin INT
  11977.     DECLARE @job_owner   sysname
  11978.     DECLARE @job_state   INT 
  11979.     DECLARE @job_id_as_char VARCHAR(36)
  11980.  
  11981.     SET NOCOUNT ON
  11982.  
  11983.     CREATE TABLE #xp_results (job_id                UNIQUEIDENTIFIER NOT NULL,
  11984.                             last_run_date         INT              NOT NULL,
  11985.                             last_run_time         INT              NOT NULL,
  11986.                             next_run_date         INT              NOT NULL,
  11987.                             next_run_time         INT              NOT NULL,
  11988.                             next_run_schedule_id  INT              NOT NULL,
  11989.                             requested_to_run      INT              NOT NULL, -- BOOL
  11990.                             request_source        INT              NOT NULL,
  11991.                             request_source_id     sysname          NULL,
  11992.                             running               INT              NOT NULL, -- BOOL
  11993.                             current_step          INT              NOT NULL,
  11994.                             current_retry_attempt INT              NOT NULL,
  11995.                             job_state             INT              NOT NULL)
  11996.  
  11997.     -- Need a job_id
  11998.     if (@job_id IS NULL)
  11999.     BEGIN
  12000.         SELECT @job_id_as_char = CONVERT(VARCHAR(36), @job_id)
  12001.         RAISERROR(14262, -1, -1, '@job_id', @job_id_as_char)
  12002.         RETURN(1) -- Failure
  12003.     END
  12004.  
  12005.     -- Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
  12006.     SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
  12007.     SELECT @job_owner = suser_sname(suser_sid())
  12008.     INSERT INTO #xp_results
  12009.     EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner
  12010.  
  12011.     -- Select the job state of the job in question
  12012.     SELECT @job_state = job_state FROM #xp_results WHERE @job_id = job_id
  12013.  
  12014.     -- Error if we have no rows selected
  12015.     if (@job_state IS NULL)
  12016.     BEGIN
  12017.         SELECT @job_id_as_char = CONVERT(VARCHAR(36), @job_id)
  12018.         RAISERROR(14262, -1, -1, '@job_id', @job_id_as_char)
  12019.         RETURN(1) -- Failure
  12020.     END
  12021.     ELSE
  12022.         SELECT @job_state
  12023.     
  12024.     -- All done
  12025.     DROP TABLE #xp_results
  12026.     RETURN(0)    -- Success
  12027. END
  12028. GO
  12029.  
  12030. raiserror('Creating procedure sp_MSrepl_isdbowner', 0,1)
  12031. go
  12032. CREATE PROCEDURE sp_MSrepl_isdbowner 
  12033.     @dbname nvarchar(255)
  12034. AS
  12035. BEGIN
  12036.     SET NOCOUNT ON
  12037.     DECLARE @retcode int
  12038.     DECLARE @cmd      nvarchar(255)
  12039.     DECLARE @isdbowner int
  12040.  
  12041.     SELECT @retcode = databaseproperty(@dbname, 'issingleuser')
  12042.     IF (@retcode = 1)
  12043.     BEGIN
  12044.         /* Database is in single user mode, so if another spid already connected,
  12045.         ** do not attempt to connect.
  12046.         */
  12047.         IF EXISTS (SELECT spid FROM sysprocesses WHERE dbid = db_id(@dbname))
  12048.             RETURN 0
  12049.     END
  12050.  
  12051.     SELECT @retcode = has_dbaccess(@dbname)
  12052.     IF (@retcode IS NULL) OR (@retcode = 0)
  12053.     BEGIN
  12054.         /* 
  12055.         ** Either no access or database not found 
  12056.         ** No need to go further
  12057.         */
  12058.         RETURN 0
  12059.     END
  12060.  
  12061.     SELECT @cmd = 'USE ' + quotename(@dbname) + ' SELECT @isdbowner = is_member(''db_owner'')'
  12062.     EXEC sp_executesql @cmd, N'@isdbowner int output', @isdbowner output
  12063.  
  12064.     RETURN isnull(@isdbowner, 0)
  12065. END
  12066. GO
  12067.  
  12068. raiserror('Creating procedure sp_MSscript_pkvar_assignment', 0,1)
  12069. go
  12070. create procedure sp_MSscript_pkvar_assignment
  12071.     @objid          int,
  12072.     @columns      binary(32), 
  12073.     @indent       int = 0,
  12074.     @identity_col sysname = NULL, -- Not null value used by trigger scripting
  12075.     @ts_col       sysname = NULL  -- Not null value used by trigger scripting    
  12076. as
  12077. -- This stored procedure will assign the '_old' var to new var
  12078. -- based on @bitmap. This is to avoid using case statement
  12079. -- in the where clause in the synctran pub proc, which
  12080. -- will cause a table scan.
  12081. -- See bug 50236
  12082.     declare @cmd          nvarchar(4000)
  12083.     declare @spacer       nvarchar(20)
  12084.     declare @indkey       int
  12085.     declare @indid        int
  12086.     declare @this_col     int
  12087.     declare @col          sysname
  12088.     declare @qualname     nvarchar(512)
  12089.     declare @column          nvarchar(255)
  12090.     declare @key          sysname
  12091.     declare @src_cols      int
  12092.  
  12093.     select @spacer = N'select ', @cmd = N''
  12094.     select @indkey = 1, @indid = 0
  12095.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  12096.     select @src_cols = count(*) from syscolumns where id = @objid
  12097.     exec dbo.sp_MSpad_command @cmd output, @indent
  12098.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  12099.  
  12100.     exec @indid = dbo.sp_MStable_has_unique_index @objid
  12101.  
  12102.     if @indid > 0
  12103.     begin
  12104.         while @indkey < 16 and index_col(@qualname, @indid, @indkey) is not null
  12105.         begin
  12106.             select @key = index_col(@qualname, @indid, @indkey)
  12107.             exec dbo.sp_MSget_col_position @objid = @objid, @columns = @columns, @key = @key, @colpos = @col output, @this_col = @this_col output
  12108.  
  12109.             select @indkey = @indkey + 1
  12110.  
  12111.             if @key in (@identity_col, @ts_col)
  12112.                 continue
  12113.                 
  12114.             select @cmd = @spacer + N'@c' + convert(nvarchar(10), @this_col)
  12115.     
  12116.             -- Get the new values for the columns in primary key.
  12117.             exec dbo.sp_MSget_synctran_column 
  12118.                     @ts_col = null,
  12119.                     @op_type = null , -- 'ins, 'upd', 'del'
  12120.                     @is_new = null,
  12121.                     @primary_key_bitmap = null,
  12122.                     @colname = null,
  12123.                     @this_col = @this_col,
  12124.                     @column = @column output,
  12125.                     @from_proc = 0,
  12126.                     @coltype = null,
  12127.                     @type = 'pk_var'    
  12128.             select @cmd = @cmd + N' = ' + @column 
  12129.             select @spacer = ',
  12130.      '
  12131.             
  12132.             -- flush command if necessary
  12133.             exec dbo.sp_MSflush_command @cmd output, 1, @indent
  12134.         end
  12135.     end
  12136. go
  12137.  
  12138. raiserror('Creating procedure sp_MSget_publication_from_taskname', 0,1)
  12139. go
  12140. create procedure sp_MSget_publication_from_taskname
  12141.     @taskname     sysname,
  12142.     @publisher    sysname, 
  12143.     @publisherdb  sysname,
  12144.     @publication  sysname OUTPUT
  12145. as
  12146.     declare @value       sysname
  12147.     declare @value2      sysname
  12148.     declare @position    INT
  12149.  
  12150.     select @publication = NULL
  12151.  
  12152.     -- Parse out publication name from the task name "publisher_publisherdb_publication_number"
  12153.     -- Expect publisher name
  12154.     if charindex(@publisher, @taskname) <> 1
  12155.     begin
  12156.         return 1
  12157.     end   
  12158.  
  12159.     -- Eat up the publisher name
  12160.     select @value = stuff(@taskname, 1, len(@publisher), N'')  
  12161.  
  12162.     -- Expect '_' + publisherdb + '_'
  12163.     select @value2 = N'_' + @publisherdb + N'_'
  12164.     if charindex(@value2, @value) <> 1
  12165.     begin
  12166.         return 1
  12167.     end
  12168.  
  12169.     -- Eat up '_' + publisherdb + '_'
  12170.     select  @value = stuff(@value, 1, LEN(@publisherdb) + 2, N'')
  12171.       
  12172.     -- Reverse the string in the hope of finding the first '_' 
  12173.     -- from the right which denotes the end of the publication 
  12174.     -- name. The number at the end should not contain '_'
  12175.     select @value2 = reverse(@value)
  12176.     select @position = charindex(N'_', @value2)
  12177.     if @position < 2
  12178.     begin
  12179.         return 1
  12180.     end
  12181.        
  12182.     select @publication = left(@value, len(@value) - @position)      
  12183.     return 0
  12184. go
  12185.  
  12186. EXEC dbo.sp_MS_marksystemobject sp_MSget_publication_from_taskname
  12187. go
  12188.  
  12189.  
  12190. raiserror('Creating procedure sp_MSrepl_check_server', 0,1)
  12191. go
  12192.  
  12193. CREATE PROCEDURE sp_MSrepl_check_server (
  12194.     @srvname sysname,
  12195.     @check_distdb bit = 0
  12196.         ) AS
  12197.     -- This sp is called by sp_dropserver to check if the server is in use by replication.
  12198.     declare @subscriber_bit smallint
  12199.     declare @distributor_bit smallint
  12200.     declare @retcode int
  12201.     declare @proc nvarchar(255)
  12202.     declare @dbname sysname
  12203.  
  12204.     -- Intialize
  12205.     select @distributor_bit = 8
  12206.     select @subscriber_bit = 4
  12207.  
  12208.     if @check_distdb = 0
  12209.     begin
  12210.         -- Check to see if the server is marked as a Distributor
  12211.         if exists (select * from sysservers where UPPER(srvname) = UPPER(@srvname) and
  12212.             srvstatus & @distributor_bit <> 0)
  12213.         begin
  12214.             raiserror(20581, 16, -1, @srvname) 
  12215.             return (1)
  12216.         end
  12217.         -- Check to see if the server is marked as a subscriber
  12218.         if exists (select * from sysservers where UPPER(srvname) = UPPER(@srvname) and
  12219.             srvstatus & @subscriber_bit <> 0)
  12220.         begin
  12221.             raiserror(20583, 16, -1, @srvname) 
  12222.             return (1)
  12223.         end
  12224.         -- Check to see if the server is a dist publisher
  12225.         if object_id('msdb.dbo.MSdistpublishers') is not null
  12226.         begin
  12227.             if exists (select * from msdb.dbo.MSdistpublishers where
  12228.                 UPPER(name) = UPPER(@srvname))
  12229.             begin
  12230.                 raiserror(20582, 16, -1, @srvname) 
  12231.                 return (1)
  12232.             end
  12233.         end
  12234.         -- Check to see if the server is in use as a subscriber in the distribution dbs.
  12235.         if object_id('msdb.dbo.MSdistributiondbs') is not null
  12236.         begin
  12237.             declare hCForEachDb CURSOR LOCAL FAST_FORWARD FOR 
  12238.                 select name from msdb.dbo.MSdistributiondbs
  12239.             FOR READ ONLY
  12240.             open hCForEachDb
  12241.             fetch hCForEachDb into @dbname
  12242.             /* Loop for each database */
  12243.             while (@@fetch_status >= 0) 
  12244.             begin
  12245.                 select @proc = quotename(@dbname) + '.dbo.sp_MSrepl_check_server'
  12246.                 exec @retcode = @proc
  12247.                     @srvname = @srvname,
  12248.                     @check_distdb = 1
  12249.                 if @retcode <> 0 or @@error <> 0
  12250.                     return (1)
  12251.                 fetch hCForEachDb into @dbname
  12252.             end /* while FETCH_SUCCESS */
  12253.         end
  12254.     end
  12255.     else
  12256.     begin
  12257.         if object_id('MSsubscriber_info') is not null
  12258.         begin
  12259.             declare @publisher sysname
  12260.             select @publisher =  publisher from MSsubscriber_info sub
  12261.                 where UPPER(subscriber) = UPPER(@srvname)
  12262.             if @publisher is not null
  12263.             begin
  12264.                 raiserror(20584, 16, -1, @srvname, @publisher) 
  12265.                 return (1)
  12266.             end
  12267.         end
  12268.     end
  12269.  
  12270. GO
  12271.  
  12272. EXEC dbo.sp_MS_marksystemobject sp_MSrepl_check_server
  12273. go
  12274.  
  12275. grant execute on dbo.sp_MSrepl_check_server to public
  12276. go
  12277.  
  12278. raiserror('Creating procedure sp_MSreset_synctran_bit', 0,1)
  12279. go
  12280. CREATE PROCEDURE sp_MSreset_synctran_bit (
  12281.     @owner          sysname,
  12282.     @table          sysname
  12283. )AS
  12284.     declare @qualified_name nvarchar(300)
  12285.     declare @synctran_bit int
  12286.  
  12287.     select @synctran_bit            = 256
  12288.     
  12289.     if @owner = N''
  12290.         select @qualified_name = @table
  12291.     else
  12292.         select @qualified_name = quotename(@owner) + '.' + quotename(@table) 
  12293.  
  12294.     -- Unmark synctran bit
  12295.     update sysobjects set replinfo = replinfo & ~@synctran_bit where 
  12296.         id = object_id(@qualified_name) and
  12297.         (replinfo & @synctran_bit) <> 0
  12298.     IF @@ERROR <> 0 
  12299.         return(1)
  12300.     return(0)
  12301. GO
  12302.  
  12303. EXEC dbo.sp_MS_marksystemobject sp_MSreset_synctran_bit
  12304. go
  12305.  
  12306. grant execute on dbo.sp_MSreset_synctran_bit to public
  12307. go
  12308.  
  12309.  
  12310. EXEC dbo.sp_MS_marksystemobject sp_MSget_jobstate
  12311. GO
  12312.  
  12313. exec dbo.sp_MS_marksystemobject sp_MSunc_to_drive
  12314. go
  12315.  
  12316. exec dbo.sp_MS_marksystemobject sp_MSrepl_isdbowner
  12317. go
  12318.  
  12319. grant execute on dbo.sp_MSget_qualified_name to public
  12320. go
  12321.  
  12322. dump tran master with no_log
  12323. go
  12324.  
  12325. grant execute on dbo.sp_helpreplicationoption to public
  12326. go
  12327.  
  12328. grant execute on dbo.sp_addpullsubscription to public
  12329. go
  12330.  
  12331. grant execute on dbo.sp_addpullsubscription_agent to public
  12332. go
  12333.  
  12334. grant execute on dbo.sp_droppullsubscription to public
  12335. go
  12336.  
  12337. grant execute on dbo.sp_helppullsubscription to public
  12338. go
  12339.  
  12340. grant execute on dbo.sp_addpullsubscription to public
  12341. go
  12342.  
  12343. grant execute on dbo.sp_addpullsubscription_agent to public
  12344. go
  12345.  
  12346. grant execute on dbo.sp_droppullsubscription to public
  12347. go
  12348.  
  12349. grant execute on dbo.sp_helppullsubscription to public
  12350. go
  12351.  
  12352. grant execute on dbo.sp_helpreplicationdboption to public
  12353. go
  12354.  
  12355. grant exec on dbo.sp_addsynctriggers to public
  12356. go
  12357.  
  12358. grant exec on dbo.sp_MScheck_agent_instance to public
  12359. go
  12360.  
  12361. grant exec on dbo.sp_get_distributor to public
  12362. go
  12363.  
  12364. grant exec on dbo.sp_table_validation to public
  12365.  
  12366. grant exec on dbo.sp_addmergepullsubscription to public
  12367.  
  12368. grant exec on dbo.sp_dropmergepullsubscription to public
  12369.  
  12370. grant exec on dbo.sp_changemergepullsubscription to public
  12371.  
  12372. grant exec on dbo.sp_helpmergepullsubscription to public
  12373.  
  12374. grant exec on dbo.sp_addmergepullsubscription_agent to public
  12375. go
  12376.  
  12377. grant exec on dbo.sp_helpsubscription_properties to public
  12378.  
  12379. grant exec on dbo.sp_change_subscription_properties to public
  12380.  
  12381. grant exec on dbo.sp_MSget_publisher_rpc to public
  12382.  
  12383. grant exec on dbo.sp_MSreplcheck_subscribe to public
  12384.  
  12385. grant exec on dbo.sp_link_publication to public
  12386.  
  12387. grant exec on dbo.sp_MS_replication_installed to public
  12388.  
  12389. grant exec on dbo.sp_MSrepl_linkedservers_rowset to public
  12390.  
  12391. grant exec on dbo.sp_MScreate_sub_tables to public
  12392.  
  12393. grant exec on dbo.sp_MSget_jobstate to public
  12394. go
  12395. grant exec on dbo.sp_MSrepl_isdbowner to public
  12396. grant exec on dbo.sp_MSscript_pkvar_assignment to public
  12397. go
  12398. grant exec on dbo.sp_MSreplraiserror to public
  12399. grant exec on dbo.sp_check_sync_trigger to public
  12400. grant exec on dbo.sp_check_for_sync_trigger to public
  12401. go
  12402. grant execute on dbo.sp_MSscript_where_clause to public
  12403. grant execute on dbo.sp_MSscript_params to public
  12404. grant execute on dbo.sp_MSscript_begintrig1 to public
  12405. grant execute on dbo.sp_MSscript_begintrig2 to public
  12406. grant execute on dbo.sp_MSscript_endtrig to public
  12407. grant execute on dbo.sp_MSscript_trigger_variables to public
  12408. grant execute on dbo.sp_MSscript_trigger_assignment to public
  12409. grant execute on dbo.sp_MSscript_trigger_fetch_statement to public
  12410. grant execute on dbo.sp_MSscript_trigger_exec_rpc  to public
  12411. grant execute on dbo.sp_MSscript_trigger_update_checks to public
  12412. grant execute on dbo.sp_MSscript_trigger_updates to public
  12413. grant execute on dbo.sp_MSscript_singlerow_trigger to public 
  12414. grant execute on dbo.sp_MSscript_multirow_trigger to public
  12415. grant execute on dbo.sp_MSscript_sync_ins_trig to public
  12416. grant execute on dbo.sp_MSscript_sync_upd_trig to public
  12417. grant execute on dbo.sp_MSscript_sync_del_trig to public
  12418. grant execute on dbo.sp_MSscript_pkvar_assignment to public
  12419. grant execute on dbo.sp_MSreplcheck_pull to public
  12420. go
  12421.  
  12422. dump tran master with no_log
  12423. go
  12424. sp_configure 'allow updates',0
  12425. go
  12426. reconfigure with override
  12427. go
  12428.  
  12429. print ''
  12430. print 'Checking objects created by replsys.sql.'
  12431. go
  12432.  
  12433. --obsolete   exec dbo.sp_check_objects 'repl'
  12434. exec dbo.sp_MS_upd_sysobj_category 2  --set sysobjects.category | 2 based on crdate.
  12435. go
  12436.  
  12437. print ''
  12438. print 'replsys.sql completed successfully.'
  12439. go
  12440.  
  12441. dump tran master with no_log
  12442. go
  12443. checkpoint
  12444. go
  12445. -- - -----
  12446.